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