File Coverage

xsh/peep.h
Criterion Covered Total %
statement 29 33 87.8
branch 6 8 75.0
condition n/a
subroutine n/a
pod n/a
total 35 41 85.3


line stmt bran cond sub pod time code
1             #ifndef XSH_PEEP_H
2             #define XSH_PEEP_H 1
3              
4             #include "caps.h" /* XSH_HAS_PERL(), XSH_THREADSAFE */
5             #include "util.h" /* XSH_ASSERT(), NOOP */
6              
7             #ifdef XSH_THREADS_H
8             # error threads.h must be loaded at the very end
9             #endif
10              
11             #ifndef XSH_HAS_RPEEP
12             # define XSH_HAS_RPEEP XSH_HAS_PERL(5, 13, 5)
13             #endif
14              
15             #define PTABLE_USE_DEFAULT 1
16             #define PTABLE_NEED_DELETE 0
17              
18             #include "ptable.h"
19              
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))
23              
24             #define XSH_THREADS_PEEP_CONTEXT 1
25              
26             typedef struct {
27             #if XSH_HAS_RPEEP
28             peep_t old_rpeep;
29             #else
30             peep_t old_peep;
31             #endif
32             ptable *seen;
33             } xsh_peep_cxt_t;
34              
35             static xsh_peep_cxt_t *xsh_peep_get_cxt(pTHX);
36              
37             static void xsh_peep_rec(pTHX_ OP *o, ptable *seen);
38              
39             #if XSH_HAS_RPEEP
40              
41 5688           static void xsh_rpeep(pTHX_ OP *o) {
42             ptable *seen;
43 5688           xsh_peep_cxt_t *cxt = xsh_peep_get_cxt(aTHX);
44              
45 5688           cxt->old_rpeep(aTHX_ o);
46              
47 5688           seen = cxt->seen;
48             XSH_ASSERT(seen);
49              
50 5688           ptable_seen_clear(seen);
51              
52 5688           xsh_peep_rec(aTHX_ o, seen);
53              
54 5688           ptable_seen_clear(seen);
55              
56 5688           return;
57             }
58              
59             #define xsh_peep_maybe_recurse(O, S) NOOP
60              
61             #else /* XSH_HAS_RPEEP */
62              
63             static void xsh_peep(pTHX_ OP *o) {
64             ptable *seen;
65             xsh_peep_cxt_t *cxt = xsh_peep_get_cxt(aTHX);
66              
67             cxt->old_peep(aTHX_ o); /* Will call the rpeep */
68              
69             seen = cxt->seen;
70             XSH_ASSERT(seen);
71              
72             ptable_seen_clear(seen);
73              
74             xsh_peep_rec(aTHX_ o, seen);
75              
76             ptable_seen_clear(seen);
77              
78             return;
79             }
80              
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))
83             switch (o->op_type) {
84             case OP_MAPWHILE:
85             case OP_GREPWHILE:
86             case OP_AND:
87             case OP_OR:
88             case OP_ANDASSIGN:
89             case OP_ORASSIGN:
90             case OP_COND_EXPR:
91             case OP_RANGE:
92             #if XSH_HAS_PERL(5, 10, 0)
93             case OP_ONCE:
94             case OP_DOR:
95             case OP_DORASSIGN:
96             #endif
97             xsh_peep_rec(aTHX_ cLOGOPo->op_other, seen);
98             break;
99             case OP_ENTERLOOP:
100             case OP_ENTERITER:
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);
104             break;
105             #if XSH_HAS_PERL(5, 9, 5)
106             case OP_SUBST:
107             xsh_peep_rec(aTHX_ cPMOPo->op_pmstashstartu.op_pmreplstart, seen);
108             break;
109             #else
110             case OP_QR:
111             case OP_MATCH:
112             case OP_SUBST:
113             xsh_peep_rec(aTHX_ cPMOPo->op_pmreplstart, seen);
114             break;
115             #endif
116             }
117              
118             return;
119             }
120              
121             #endif /* !XSH_HAS_RPEEP */
122              
123 96741           static int xsh_peep_seen(pTHX_ OP *o, ptable *seen) {
124             #define xsh_peep_seen(O, S) xsh_peep_seen(aTHX_ (O), (S))
125             #if XSH_HAS_RPEEP
126 96741 100         switch (o->op_type) {
127             case OP_NEXTSTATE:
128             case OP_DBSTATE:
129             case OP_UNSTACK:
130             case OP_STUB:
131 16820           break;
132             default:
133 79921           return 0;
134             }
135             #endif /* XSH_HAS_RPEEP */
136              
137 16820 100         if (ptable_fetch(seen, o))
138 1           return 1;
139              
140 16819           ptable_seen_store(seen, o, o);
141              
142 16819           return 0;
143             }
144              
145 15           static void xsh_peep_local_setup(pTHX_ xsh_peep_cxt_t *cxt) {
146             #if XSH_HAS_RPEEP
147 15 50         if (PL_rpeepp != xsh_rpeep) {
148 15           cxt->old_rpeep = PL_rpeepp;
149 15           PL_rpeepp = xsh_rpeep;
150             } else {
151 0           cxt->old_rpeep = 0;
152             }
153             #else
154             if (PL_peepp != xsh_peep) {
155             cxt->old_peep = PL_peepp;
156             PL_peepp = xsh_peep;
157             } else {
158             cxt->old_peep = 0;
159             }
160             #endif
161              
162 15           cxt->seen = ptable_new(32);
163 15           }
164              
165 15           static void xsh_peep_local_teardown(pTHX_ xsh_peep_cxt_t *cxt) {
166 15           ptable_seen_free(cxt->seen);
167 15           cxt->seen = NULL;
168              
169             #if XSH_HAS_RPEEP
170 15 50         if (cxt->old_rpeep) {
171 15           PL_rpeepp = cxt->old_rpeep;
172 15           cxt->old_rpeep = 0;
173             }
174             #else
175             if (cxt->old_peep) {
176             PL_peepp = cxt->old_peep;
177             cxt->old_peep = 0;
178             }
179             #endif
180              
181 15           return;
182             }
183              
184 0           static void xsh_peep_clone(pTHX_ const xsh_peep_cxt_t *old_cxt, xsh_peep_cxt_t *new_cxt) {
185 0           new_cxt->seen = ptable_new(32);
186              
187 0           return;
188             }
189              
190             #endif /* XSH_PEEP_H */