File Coverage

lib/Optree/Generate.xs
Criterion Covered Total %
statement 77 80 96.2
branch 16 24 66.6
condition n/a
subroutine n/a
pod n/a
total 93 104 89.4


line stmt bran cond sub pod time code
1             /* You may distribute under the terms of either the GNU General Public License
2             * or the Artistic License (the same terms as Perl itself)
3             *
4             * (C) Paul Evans, 2023 -- leonerd@leonerd.org.uk
5             */
6             #include "EXTERN.h"
7             #include "perl.h"
8             #include "XSUB.h"
9              
10             #include "perl-backcompat.c.inc"
11             #include "perl-additions.c.inc"
12              
13             #include "newSVop.c.inc"
14              
15             #define ENTER_and_setup_pad(name) S_ENTER_and_setup_pad(aTHX_ name)
16 51           static void S_ENTER_and_setup_pad(pTHX_ const char *name)
17             {
18 51 50         if(!PL_compcv)
19 0           croak("Cannot call %s while not compiling a subroutine", name);
20              
21 51           ENTER;
22              
23 51           PAD_SET_CUR(CvPADLIST(PL_compcv), 1);
24              
25 51           SAVESPTR(PL_comppad_name);
26 51           PL_comppad_name = PadlistNAMES(CvPADLIST(PL_compcv));
27 51           }
28              
29 12           static void S_setup_constants(pTHX)
30             {
31 12           HV *stash;
32 12           AV *export;
33              
34             #define DO_CONSTANT(c) \
35             newCONSTSUB(stash, #c, newSViv(c)); \
36             av_push(export, newSVpv(#c, 0))
37              
38 12           stash = gv_stashpvs("Optree::Generate", TRUE);
39 12           export = get_av("Optree::Generate::EXPORT_OK", TRUE);
40              
41 12           DO_CONSTANT(G_SCALAR);
42 12           DO_CONSTANT(G_LIST);
43 12           DO_CONSTANT(G_VOID);
44              
45 12           DO_CONSTANT(OPf_WANT);
46 12           DO_CONSTANT(OPf_WANT_VOID);
47 12           DO_CONSTANT(OPf_WANT_SCALAR);
48 12           DO_CONSTANT(OPf_WANT_LIST);
49 12           DO_CONSTANT(OPf_KIDS);
50 12           DO_CONSTANT(OPf_PARENS);
51 12           DO_CONSTANT(OPf_REF);
52 12           DO_CONSTANT(OPf_MOD);
53 12           DO_CONSTANT(OPf_STACKED);
54 12           DO_CONSTANT(OPf_SPECIAL);
55 12           }
56              
57             MODULE = Optree::Generate PACKAGE = Optree::Generate
58              
59             I32 opcode(const char *opname)
60             CODE:
61 4275 50         for(RETVAL = 0; RETVAL < OP_max; RETVAL++)
62 4205 100         if(strEQ(opname, PL_op_name[RETVAL]))
63 70           goto found;
64 0           croak("Unrecognised opcode(\"%s\")", opname);
65 70           found:
66 70 100         ;
67             OUTPUT:
68             RETVAL
69              
70             SV *
71             op_contextualize(SV *o, I32 context)
72             CODE:
73 1           ENTER_and_setup_pad("op_contextualize");
74 1           RETVAL = newSVop(op_contextualize(SvOPo(o), context));
75 1           LEAVE;
76             OUTPUT:
77             RETVAL
78              
79             SV *
80             op_scope(SV *o)
81             CODE:
82 2           ENTER_and_setup_pad("op_scope");
83 2           RETVAL = newSVop(op_scope(SvOPo(o)));
84 2           LEAVE;
85             OUTPUT:
86             RETVAL
87              
88             SV *
89             newOP(I32 type, I32 flags)
90             CODE:
91 2           ENTER_and_setup_pad("newOP");
92 2           RETVAL = newSVop(newOP(type, flags));
93 2           LEAVE;
94             OUTPUT:
95             RETVAL
96              
97             SV *
98             newASSIGNOP(I32 flags, SV *left, I32 optype, SV *right)
99             CODE:
100 1           ENTER_and_setup_pad("newASSIGNOP");
101 1           RETVAL = newSVop(newASSIGNOP(flags, SvOPo(left), optype, SvOPo(right)));
102 1           LEAVE;
103             OUTPUT:
104             RETVAL
105              
106             SV *
107             newBINOP(I32 type, I32 flags, SV *first, SV *last)
108             CODE:
109 3           ENTER_and_setup_pad("newBINOP");
110 3           RETVAL = newSVop(newBINOP(type, flags, SvOPo(first), SvOPo(last)));
111 3           LEAVE;
112             OUTPUT:
113             RETVAL
114              
115             SV *
116             newCONDOP(I32 flags, SV *first, SV *trueop, SV *falseop)
117             CODE:
118 1           ENTER_and_setup_pad("newCONDOP");
119 1           RETVAL = newSVop(newCONDOP(flags, SvOPo(first), SvOPo(trueop), SvOPo(falseop)));
120 1           LEAVE;
121             OUTPUT:
122             RETVAL
123              
124             SV *
125             newFOROP(I32 flags, SV *sv, SV *expr, SV *block, SV *cont)
126             CODE:
127 1           ENTER_and_setup_pad("newFOROP");
128 1 50         RETVAL = newSVop(newFOROP(flags, maySvOPo(sv), SvOPo(expr), SvOPo(block), maySvOPo(cont)));
    50          
    50          
    50          
129 1           LEAVE;
130             OUTPUT:
131             RETVAL
132              
133             SV *
134             newGVOP(I32 type, I32 flags, SV *gv)
135             CODE:
136 3 50         if(!SvROK(gv) || SvTYPE(SvRV(gv)) != SVt_PVGV)
    50          
137 0           croak("Expected a GLOB ref to newGVOP");
138 3           ENTER_and_setup_pad("newGVOP");
139 3           RETVAL = newSVop(newGVOP(type, flags, (GV *)SvRV(gv)));
140 3           LEAVE;
141             OUTPUT:
142             RETVAL
143              
144             SV *
145             newLISTOP(I32 type, I32 flags, ...)
146             CODE:
147 8           ENTER_and_setup_pad("newLISTOP");
148             /* Can't use newLISTOPn() here because of a variable number of kid ops */
149 8           OP *o = newLISTOP(OP_LIST, 0, NULL, NULL);
150 24 100         for(U32 i = 2; i < items; i++)
151 16           o = op_append_elem(OP_LIST, o, SvOPo(ST(i)));
152 8 100         if(type != OP_LIST)
153 7           o = op_convert_list(type, flags, o);
154 8           RETVAL = newSVop(o);
155 8           LEAVE;
156             OUTPUT:
157             RETVAL
158              
159             SV *
160             newLOGOP(I32 type, I32 flags, SV *first, SV *other)
161             CODE:
162 2           ENTER_and_setup_pad("newLOGOP");
163 2           RETVAL = newSVop(newLOGOP(type, flags, SvOPo(first), SvOPo(other)));
164 2           LEAVE;
165             OUTPUT:
166             RETVAL
167              
168             SV *
169             newPADxVOP(I32 type, I32 flags, U32 padoffset)
170             CODE:
171 1           ENTER_and_setup_pad("newPADxVOP");
172 1           RETVAL = newSVop(newPADxVOP(type, flags, padoffset));
173 1           LEAVE;
174             OUTPUT:
175             RETVAL
176              
177             SV *
178             newSVOP(I32 type, I32 flags, SV *sv)
179             CODE:
180 21           ENTER_and_setup_pad("newSVOP");
181 21           RETVAL = newSVop(newSVOP(type, flags, newSVsv(sv)));
182 21           LEAVE;
183             OUTPUT:
184             RETVAL
185              
186             SV *
187             newUNOP(I32 type, I32 flags, SV *first)
188             CODE:
189 5           ENTER_and_setup_pad("newUNOP");
190 5           RETVAL = newSVop(newUNOP(type, flags, SvOPo(first)));
191 5           LEAVE;
192             OUTPUT:
193             RETVAL
194              
195             BOOT:
196 12           S_setup_constants(aTHX);