File Coverage

xs/Type.xs
Criterion Covered Total %
statement 99 117 84.6
branch 58 62 93.5
condition n/a
subroutine n/a
pod n/a
total 157 179 87.7


line stmt bran cond sub pod time code
1             MODULE = FFI::Platypus PACKAGE = FFI::Platypus::Type
2              
3             BOOT:
4             {
5 56           HV *ft = get_hv("FFI::Platypus::TypeParser::ffi_type", GV_ADD);
6 56           hv_stores(ft, "void", newSViv(PTR2IV( &ffi_type_void )));
7 56           hv_stores(ft, "sint8", newSViv(PTR2IV( &ffi_type_sint8 )));
8 56           hv_stores(ft, "sint16", newSViv(PTR2IV( &ffi_type_sint16 )));
9 56           hv_stores(ft, "sint32", newSViv(PTR2IV( &ffi_type_sint32 )));
10 56           hv_stores(ft, "sint64", newSViv(PTR2IV( &ffi_type_sint64 )));
11 56           hv_stores(ft, "uint8", newSViv(PTR2IV( &ffi_type_uint8 )));
12 56           hv_stores(ft, "uint16", newSViv(PTR2IV( &ffi_type_uint16 )));
13 56           hv_stores(ft, "uint32", newSViv(PTR2IV( &ffi_type_uint32 )));
14 56           hv_stores(ft, "uint64", newSViv(PTR2IV( &ffi_type_uint64 )));
15 56           hv_stores(ft, "pointer", newSViv(PTR2IV( &ffi_type_pointer )));
16 56           hv_stores(ft, "float", newSViv(PTR2IV( &ffi_type_float )));
17 56           hv_stores(ft, "double", newSViv(PTR2IV( &ffi_type_double )));
18             #ifdef FFI_PL_PROBE_LONGDOUBLE
19 56           hv_stores(ft, "longdouble", newSViv(PTR2IV( &ffi_type_longdouble )));
20             #endif
21             #ifdef FFI_PL_PROBE_COMPLEX
22 56           hv_stores(ft, "complex_float", newSViv(PTR2IV( &ffi_type_complex_float )));
23 56           hv_stores(ft, "complex_double", newSViv(PTR2IV( &ffi_type_complex_double )));
24             #endif
25             }
26              
27             SV*
28             meta(self)
29             ffi_pl_type *self
30             PREINIT:
31             HV *meta;
32             CODE:
33 491           meta = ffi_pl_get_type_meta(self);
34 491           RETVAL = newRV_noinc((SV*)meta);
35             OUTPUT:
36             RETVAL
37              
38             int
39             sizeof(self)
40             ffi_pl_type *self
41             CODE:
42 306           RETVAL = ffi_pl_sizeof(self);
43             OUTPUT:
44             RETVAL
45              
46             SV*
47             unitof(self)
48             ffi_pl_type *self
49             PREINIT:
50             int type_code;
51             CODE:
52 19           type_code = self->type_code;
53              
54             /* ignore custom asoect */
55 19 100         if((type_code & FFI_PL_SHAPE_MASK) == FFI_PL_SHAPE_CUSTOM_PERL)
56             {
57 1           type_code ^= FFI_PL_SHAPE_CUSTOM_PERL;
58             }
59              
60 19           switch(type_code)
61             {
62             case FFI_PL_TYPE_SINT8 | FFI_PL_SHAPE_POINTER:
63             case FFI_PL_TYPE_SINT8 | FFI_PL_SHAPE_ARRAY:
64 6           XSRETURN_PV("sint8");
65             case FFI_PL_TYPE_UINT8 | FFI_PL_SHAPE_POINTER:
66             case FFI_PL_TYPE_UINT8 | FFI_PL_SHAPE_ARRAY:
67 0           XSRETURN_PV("uint8");
68             case FFI_PL_TYPE_SINT16 | FFI_PL_SHAPE_POINTER:
69             case FFI_PL_TYPE_SINT16 | FFI_PL_SHAPE_ARRAY:
70 0           XSRETURN_PV("sint16");
71             case FFI_PL_TYPE_UINT16 | FFI_PL_SHAPE_POINTER:
72             case FFI_PL_TYPE_UINT16 | FFI_PL_SHAPE_ARRAY:
73 0           XSRETURN_PV("uint16");
74             case FFI_PL_TYPE_SINT32 | FFI_PL_SHAPE_POINTER:
75             case FFI_PL_TYPE_SINT32 | FFI_PL_SHAPE_ARRAY:
76 0           XSRETURN_PV("sint32");
77             case FFI_PL_TYPE_UINT32 | FFI_PL_SHAPE_POINTER:
78             case FFI_PL_TYPE_UINT32 | FFI_PL_SHAPE_ARRAY:
79 0           XSRETURN_PV("uint32");
80             case FFI_PL_TYPE_SINT64 | FFI_PL_SHAPE_POINTER:
81             case FFI_PL_TYPE_SINT64 | FFI_PL_SHAPE_ARRAY:
82 0           XSRETURN_PV("sint64");
83             case FFI_PL_TYPE_UINT64 | FFI_PL_SHAPE_POINTER:
84             case FFI_PL_TYPE_UINT64 | FFI_PL_SHAPE_ARRAY:
85 0           XSRETURN_PV("uint64");
86             case FFI_PL_TYPE_FLOAT | FFI_PL_SHAPE_POINTER:
87             case FFI_PL_TYPE_FLOAT | FFI_PL_SHAPE_ARRAY:
88 0           XSRETURN_PV("float");
89             case FFI_PL_TYPE_DOUBLE | FFI_PL_SHAPE_POINTER:
90             case FFI_PL_TYPE_DOUBLE | FFI_PL_SHAPE_ARRAY:
91 0           XSRETURN_PV("double");
92             #ifdef FFI_PL_PROBE_LONGDOUBLE
93             case FFI_PL_TYPE_LONG_DOUBLE | FFI_PL_SHAPE_POINTER:
94             case FFI_PL_TYPE_LONG_DOUBLE | FFI_PL_SHAPE_ARRAY:
95 0           XSRETURN_PV("longdouble");
96             #endif
97             #ifdef FFI_PL_PROBE_COMPLEX
98             case FFI_PL_TYPE_COMPLEX_FLOAT | FFI_PL_SHAPE_POINTER:
99             case FFI_PL_TYPE_COMPLEX_FLOAT | FFI_PL_SHAPE_ARRAY:
100 0           XSRETURN_PV("complex_float");
101              
102             case FFI_PL_TYPE_COMPLEX_DOUBLE | FFI_PL_SHAPE_POINTER:
103             case FFI_PL_TYPE_COMPLEX_DOUBLE | FFI_PL_SHAPE_ARRAY:
104 0           XSRETURN_PV("complex_double");
105             #endif
106             default:
107 13           XSRETURN_UNDEF;
108             }
109              
110             const char *
111             kindof(self)
112             ffi_pl_type *self
113             PREINIT:
114             int type_code;
115             CODE:
116 19           type_code = self->type_code;
117              
118             /* ignore custom asoect */
119 19 100         if((type_code & FFI_PL_SHAPE_MASK) == FFI_PL_SHAPE_CUSTOM_PERL)
120             {
121 4           type_code ^= FFI_PL_SHAPE_CUSTOM_PERL;
122             }
123              
124 19           switch(type_code)
125             {
126             case FFI_PL_TYPE_VOID :
127 1           RETVAL = "void";
128 1           break;
129              
130             case FFI_PL_TYPE_SINT8:
131             case FFI_PL_TYPE_UINT8:
132             case FFI_PL_TYPE_SINT16:
133             case FFI_PL_TYPE_UINT16:
134             case FFI_PL_TYPE_SINT32:
135             case FFI_PL_TYPE_UINT32:
136             case FFI_PL_TYPE_SINT64:
137             case FFI_PL_TYPE_UINT64:
138             case FFI_PL_TYPE_FLOAT:
139             case FFI_PL_TYPE_DOUBLE:
140             case FFI_PL_TYPE_LONG_DOUBLE:
141             case FFI_PL_TYPE_COMPLEX_FLOAT:
142             case FFI_PL_TYPE_COMPLEX_DOUBLE:
143             case FFI_PL_TYPE_OPAQUE:
144 3           RETVAL = "scalar";
145 3           break;
146              
147             case FFI_PL_TYPE_STRING:
148 3           RETVAL = "string";
149 3           break;
150              
151             case FFI_PL_TYPE_CLOSURE:
152 0           RETVAL = "closure";
153 0           break;
154              
155             case FFI_PL_TYPE_RECORD:
156 4           RETVAL = "record";
157 4           break;
158              
159             case FFI_PL_TYPE_RECORD_VALUE:
160 2           RETVAL = "record-value";
161 2           break;
162              
163             default:
164 6           switch(type_code & FFI_PL_SHAPE_MASK)
165             {
166             case FFI_PL_SHAPE_POINTER:
167 2           RETVAL = "pointer";
168 2           break;
169             case FFI_PL_SHAPE_ARRAY:
170 4           RETVAL = "array";
171 4           break;
172             case FFI_PL_SHAPE_OBJECT:
173 0           RETVAL = "object";
174 0           break;
175             default:
176 0           croak("internal error computing type kind (%x)", type_code);
177             }
178             }
179             OUTPUT:
180             RETVAL
181              
182             int
183             countof(self)
184             ffi_pl_type *self
185             CODE:
186 19           switch(self->type_code & FFI_PL_SHAPE_MASK)
187             {
188             case FFI_PL_SHAPE_SCALAR:
189             case FFI_PL_SHAPE_POINTER:
190             case FFI_PL_SHAPE_CUSTOM_PERL:
191             case FFI_PL_SHAPE_OBJECT:
192 15 100         switch(self->type_code)
193             {
194             case FFI_PL_TYPE_VOID:
195 1           RETVAL = 0;
196 1           break;
197             default:
198 14           RETVAL = 1;
199 14           break;
200             }
201 15           break;
202              
203             case FFI_PL_SHAPE_ARRAY:
204 4           RETVAL = self->extra[0].array.element_count;
205 4           break;
206              
207             default:
208 0           croak("internal error computing type kind (%x)", self->type_code);
209             }
210             OUTPUT:
211             RETVAL
212              
213             int
214             type_code(self)
215             ffi_pl_type *self
216             CODE:
217 568           RETVAL = self->type_code;
218             OUTPUT:
219             RETVAL
220              
221             int
222             is_record(self)
223             ffi_pl_type *self
224             CODE:
225             /* may not need this method anymore */
226 26           RETVAL = self->type_code == FFI_PL_TYPE_RECORD
227 13 100         || self->type_code == (FFI_PL_TYPE_RECORD | FFI_PL_SHAPE_CUSTOM_PERL);
    100          
228             OUTPUT:
229             RETVAL
230              
231             int
232             is_record_value(self)
233             ffi_pl_type *self
234             CODE:
235 40           RETVAL = self->type_code == FFI_PL_TYPE_RECORD_VALUE
236 20 100         || self->type_code == (FFI_PL_TYPE_RECORD_VALUE | FFI_PL_SHAPE_CUSTOM_PERL);
    100          
237             OUTPUT:
238             RETVAL
239              
240             int
241             is_customizable(self)
242             ffi_pl_type *self
243             PREINIT:
244             int shape;
245             int base;
246             CODE:
247 207           shape = self->type_code & FFI_PL_SHAPE_MASK;
248 207           base = self->type_code & FFI_PL_BASE_MASK;
249 207           RETVAL = shape == FFI_PL_SHAPE_SCALAR
250 363 100         && ( base == FFI_PL_BASE_SINT
    100          
251 156 100         || base == FFI_PL_BASE_UINT
252 69 100         || base == FFI_PL_BASE_FLOAT
253 39 100         || base == FFI_PL_BASE_OPAQUE
254 2 100         || base == FFI_PL_BASE_RECORD
255 1 50         || base == (FFI_PL_BASE_RECORD | FFI_PL_BASE_OPAQUE)
256             );
257             OUTPUT:
258             RETVAL
259              
260             int
261             is_object_ok(self)
262             ffi_pl_type *self
263             PREINIT:
264             int shape;
265             int base;
266             CODE:
267 26           shape = self->type_code & FFI_PL_SHAPE_MASK;
268 26           base = self->type_code & FFI_PL_BASE_MASK;
269 26           RETVAL = shape == FFI_PL_SHAPE_SCALAR
270 42 50         && ( base == FFI_PL_BASE_SINT
    100          
271 16 100         || base == FFI_PL_BASE_UINT
272 8 100         || base == FFI_PL_BASE_OPAQUE
273             );
274             OUTPUT:
275             RETVAL
276              
277             int
278             is_ro(self)
279             ffi_pl_type *self
280             CODE:
281 6 50         RETVAL = self->type_code == FFI_PL_TYPE_STRING &&
    100          
282 6           self->sub_type == FFI_PL_TYPE_STRING_RO;
283             OUTPUT:
284             RETVAL
285              
286             void
287             DESTROY(self)
288             ffi_pl_type *self
289             CODE:
290 2434 100         if(self->type_code == FFI_PL_TYPE_CLOSURE)
291             {
292 89 100         if(!PL_dirty)
293 89           Safefree(self->extra[0].closure.ffi_cif.arg_types);
294             }
295 2345 100         else if(self->type_code == FFI_PL_TYPE_RECORD
296 2280 100         || self->type_code == FFI_PL_TYPE_RECORD_VALUE)
297             {
298 100 100         if(self->extra[0].record.class != NULL)
299 28           free(self->extra[0].record.class);
300             }
301             else
302             {
303 2273           switch(self->type_code & FFI_PL_SHAPE_MASK)
304             {
305             case FFI_PL_SHAPE_CUSTOM_PERL:
306             {
307             ffi_pl_type_extra_custom_perl *custom;
308              
309 209           custom = &self->extra[0].custom_perl;
310              
311 209 100         if(custom->perl_to_native != NULL)
312 107           SvREFCNT_dec(custom->perl_to_native);
313 209 100         if(custom->perl_to_native_post != NULL)
314 62           SvREFCNT_dec(custom->perl_to_native_post);
315 209 100         if(custom->native_to_perl != NULL)
316 127           SvREFCNT_dec(custom->native_to_perl);
317 209 100         if(self->extra[0].record.class != NULL)
318 4           free(self->extra[0].record.class);
319             }
320 209           break;
321             case FFI_PL_SHAPE_OBJECT:
322             {
323 24 50         if(self->extra[0].object.class != NULL)
324 24           free(self->extra[0].object.class);
325             }
326 24           break;
327             default:
328 2040           break;
329             }
330             }
331 2434 100         if(!PL_dirty)
332 230           Safefree(self);
333