File Coverage

XS.xs
Criterion Covered Total %
statement 65 65 100.0
branch 50 120 41.6
condition n/a
subroutine n/a
pod n/a
total 115 185 62.1


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2              
3             #ifdef __cplusplus
4             extern "C++" {
5             #include
6             }
7             #endif
8              
9             extern "C" {
10             #include "EXTERN.h"
11             #include "perl.h"
12             #include "XSUB.h"
13             }
14              
15             static MGVTBL sv_payload_marker;
16             static bool optimize_entersub = 1;
17             static int unstolen = 0;
18              
19             #include "xs/compat.h"
20             #include "xs/types.h"
21             #include "xs/accessors.h"
22             #include "xs/installer.h"
23              
24             static void
25 55           CAIXS_install_inherited_accessor(pTHX_ SV* full_name, SV* hash_key, SV* pkg_key, SV* read_cb, SV* write_cb, int opts) {
26             shared_keys* payload;
27 55 100         bool need_cb = read_cb && write_cb;
    50          
28              
29 55 100         if (need_cb) {
30             assert(pkg_key != NULL);
31              
32 12 100         if (opts & IsNamed) {
33 2           payload = CAIXS_install_accessor(aTHX_ full_name, (AccessorOpts)(opts & ~IsNamed));
34             } else {
35 12           payload = CAIXS_install_accessor(aTHX_ full_name, (AccessorOpts)opts);
36             }
37              
38 43 100         } else if (pkg_key != NULL) {
39 37           payload = CAIXS_install_accessor(aTHX_ full_name, (AccessorOpts)opts);
40              
41             } else {
42 6           payload = CAIXS_install_accessor(aTHX_ full_name, (AccessorOpts)opts);
43             }
44              
45             STRLEN len;
46 55 50         const char* hash_key_buf = SvPV_const(hash_key, len);
47 55 100         SV* s_hash_key = newSVpvn_share(hash_key_buf, SvUTF8(hash_key) ? -(I32)len : (I32)len, 0);
48 55           payload->hash_key = s_hash_key;
49              
50 55 100         if (pkg_key != NULL) {
51 49 50         const char* pkg_key_buf = SvPV_const(pkg_key, len);
52 49 100         SV* s_pkg_key = newSVpvn_share(pkg_key_buf, SvUTF8(pkg_key) ? -(I32)len : (I32)len, 0);
53 49           payload->pkg_key = s_pkg_key;
54             }
55              
56 55 100         if (need_cb) {
57 12 100         if (SvROK(read_cb) && SvTYPE(SvRV(read_cb)) == SVt_PVCV) {
    50          
58 10           payload->read_cb = SvREFCNT_inc_NN(SvRV(read_cb));
59             } else {
60 2           payload->read_cb = NULL;
61             }
62              
63 12 100         if (SvROK(write_cb) && SvTYPE(SvRV(write_cb)) == SVt_PVCV) {
    50          
64 7           payload->write_cb = SvREFCNT_inc_NN(SvRV(write_cb));
65             } else {
66 12           payload->write_cb = NULL;
67             }
68             }
69 55           }
70              
71             static void
72 29           CAIXS_install_class_accessor(pTHX_ SV* full_name, SV* default_sv, bool is_varclass, int opts) {
73 29 100         bool is_lazy = SvROK(default_sv) && SvTYPE(SvRV(default_sv)) == SVt_PVCV;
    50          
74              
75             shared_keys* payload;
76 29 100         if (is_lazy) {
77 8           payload = CAIXS_install_accessor(aTHX_ full_name, (AccessorOpts)opts);
78              
79             } else {
80 21           payload = CAIXS_install_accessor(aTHX_ full_name, (AccessorOpts)opts);
81             }
82              
83 29 100         if (is_varclass) {
84 10           GV* gv = gv_fetchsv(full_name, GV_ADD, SVt_PV);
85             assert(gv);
86              
87 10           payload->storage = GvSV(gv);
88             assert(payload->storage);
89              
90             /* We take ownership of this glob slot, so if someone changes the glob - they're in trouble */
91 10           SvREFCNT_inc_simple_void_NN(payload->storage);
92              
93             } else {
94 19           payload->storage = newSV(0);
95             }
96              
97 29 100         if (SvOK(default_sv)) {
    50          
    50          
98 10 100         if (is_lazy) {
99 8           payload->lazy_cb = SvREFCNT_inc_NN(SvRV(default_sv));
100              
101             } else {
102 2           sv_setsv(payload->storage, default_sv);
103             }
104             }
105 29           }
106              
107             MODULE = Class::Accessor::Inherited::XS PACKAGE = Class::Accessor::Inherited::XS
108             PROTOTYPES: DISABLE
109              
110             BOOT:
111             {
112 38           SV** check_env = hv_fetch(GvHV(PL_envgv), "CAIXS_DISABLE_ENTERSUB", 22, 0);
113 38 50         if (check_env && SvTRUE(*check_env)) optimize_entersub = 0;
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
114             #ifdef CAIX_OPTIMIZE_OPMETHOD
115             MUTEX_LOCK(&PL_my_ctx_mutex);
116 38           qsort(accessor_map, ACCESSOR_MAP_SIZE, sizeof(accessor_cb_pair_t), CAIXS_map_compare);
117             MUTEX_UNLOCK(&PL_my_ctx_mutex);
118             #endif
119 38           HV* stash = gv_stashpv("Class::Accessor::Inherited::XS", 0);
120 38           newCONSTSUB(stash, "BINARY_UNSAFE", CAIX_BINARY_UNSAFE_RESULT);
121 38           newCONSTSUB(stash, "OPTIMIZED_OPMETHOD", CAIX_OPTIMIZE_OPMETHOD_RESULT);
122             }
123              
124             void
125             install_object_accessor(SV* full_name, SV* hash_key, int opts)
126             PPCODE:
127             {
128 6           CAIXS_install_inherited_accessor(aTHX_ full_name, hash_key, NULL, NULL, NULL, opts);
129 6           XSRETURN_UNDEF;
130             }
131              
132             void
133             install_inherited_accessor(SV* full_name, SV* hash_key, SV* pkg_key, int opts)
134             PPCODE:
135             {
136 37           CAIXS_install_inherited_accessor(aTHX_ full_name, hash_key, pkg_key, NULL, NULL, opts);
137 37           XSRETURN_UNDEF;
138             }
139              
140             void
141             install_inherited_cb_accessor(SV* full_name, SV* hash_key, SV* pkg_key, SV* read_cb, SV* write_cb, int opts)
142             PPCODE:
143             {
144 12           CAIXS_install_inherited_accessor(aTHX_ full_name, hash_key, pkg_key, read_cb, write_cb, opts);
145 12           XSRETURN_UNDEF;
146             }
147              
148             void
149             install_class_accessor(SV* full_name, SV* default_sv, SV* is_varclass, SV* opts)
150             PPCODE:
151             {
152 29 50         CAIXS_install_class_accessor(aTHX_ full_name, default_sv, SvTRUE(is_varclass), SvIV(opts));
    50          
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    0          
153 29           XSRETURN_UNDEF;
154             }
155              
156             void
157             install_constructor(SV* full_name)
158             PPCODE:
159             {
160 2           CAIXS_install_cv(aTHX_ full_name);
161 2           XSRETURN_UNDEF;
162             }
163              
164             MODULE = Class::Accessor::Inherited::XS PACKAGE = Class::Accessor::Inherited::XS::Constants
165             PROTOTYPES: DISABLE
166              
167             BOOT:
168             {
169 38           HV* stash = gv_stashpv("Class::Accessor::Inherited::XS::Constants", GV_ADD);
170 38           AV* exp = get_av("Class::Accessor::Inherited::XS::Constants::EXPORT", GV_ADD);
171             #define RGSTR(c) \
172             newCONSTSUB(stash, #c , newSViv(c)); \
173             av_push(exp, newSVpvn(#c, strlen(#c)));
174 38           RGSTR(None);
175 38           RGSTR(IsReadonly);
176 38           RGSTR(IsWeak);
177 38           RGSTR(IsNamed);
178              
179 38           AV* isa = get_av("Class::Accessor::Inherited::XS::Constants::ISA", GV_ADD);
180 38           av_push(isa, newSVpvs("Exporter"));
181              
182 38           hv_stores(get_hv("INC", GV_ADD), "Class/Accessor/Inherited/XS/Constants.pm", &PL_sv_yes);
183             }
184              
185             MODULE = Class::Accessor::Inherited::XS PACKAGE = Class::Accessor::Inherited::XS::Debug
186             PROTOTYPES: DISABLE
187              
188             void unstolen_count()
189             PPCODE:
190             {
191 5           XSRETURN_IV(unstolen);
192             }