File Coverage

xs/util.h
Criterion Covered Total %
statement 27 30 90.0
branch 27 40 67.5
condition n/a
subroutine n/a
pod n/a
total 54 70 77.1


line stmt bran cond sub pod time code
1             #ifndef __INHERITED_XS_UTIL_H_
2             #define __INHERITED_XS_UTIL_H_
3              
4             inline MAGIC*
5             CAIXS_mg_findext(SV* sv, int type, MGVTBL* vtbl) {
6             MAGIC* mg;
7              
8             if (sv) {
9             for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
10             if (mg->mg_type == type && mg->mg_virtual == vtbl) {
11             return mg;
12             }
13             }
14             }
15              
16             return NULL;
17             }
18              
19             inline shared_keys*
20 417           CAIXS_find_payload(CV* cv) {
21             shared_keys* payload;
22              
23             #ifndef MULTIPLICITY
24             /* Blessed are ye and get a fastpath */
25 417           payload = (shared_keys*)(CvXSUBANY(cv).any_ptr);
26 417 50         if (UNLIKELY(!payload)) croak("Can't find hash key information");
27             #else
28             /*
29             We can't look into CvXSUBANY under threads, as it could have been written in the parent thread
30             and had gone away at any time without prior notice. So, instead, we have to scan our magical
31             refcnt storage - there's always a proper thread-local SV*, cloned for us by perl itself.
32             */
33             MAGIC* mg = CAIXS_mg_findext((SV*)cv, PERL_MAGIC_ext, &sv_payload_marker);
34             if (UNLIKELY(!mg)) croak("Can't find hash key information");
35              
36             payload = (shared_keys*)AvARRAY((AV*)(mg->mg_obj));
37             #endif
38              
39 417           return payload;
40             }
41              
42             inline HV*
43 134           CAIXS_find_stash(pTHX_ SV* self, CV* cv) {
44             HV* stash;
45              
46 134 100         if (SvROK(self)) {
47 16           stash = SvSTASH(SvRV(self));
48              
49             } else {
50 118           GV* acc_gv = CvGV(cv);
51 118 50         if (UNLIKELY(!acc_gv)) croak("Can't have package accessor in anon sub");
52 118           stash = GvSTASH(acc_gv);
53              
54 118 50         const char* stash_name = HvENAME(stash);
    50          
    50          
    50          
    50          
    50          
55 118 100         const char* self_name = SvPV_nolen(self);
56 118 100         if (strcmp(stash_name, self_name) != 0) {
57 21           stash = gv_stashsv(self, GV_ADD);
58 21 50         if (UNLIKELY(!stash)) croak("Couldn't get required stash");
59             }
60             }
61              
62 134           return stash;
63             }
64              
65             static GV*
66 191           CAIXS_fetch_glob(pTHX_ HV* stash, SV* pkg_key) {
67 191           HE* hent = hv_fetch_ent(stash, pkg_key, 0, 0);
68 191 100         GV* glob = hent ? (GV*)HeVAL(hent) : NULL;
69              
70 191 100         if (UNLIKELY(!glob || !isGV(glob) || SvFAKE(glob))) {
    50          
    100          
    50          
71 55 50         if (!glob) glob = (GV*)newSV(0);
72              
73 55           gv_init_sv(glob, stash, pkg_key, 0);
74              
75 55 50         if (hent) {
76             /* There was just a stub instead of the full glob */
77 0           SvREFCNT_inc_simple_void_NN((SV*)glob);
78 0           SvREFCNT_dec_NN(HeVAL(hent));
79 0           HeVAL(hent) = (SV*)glob;
80              
81             } else {
82 55 100         if (!hv_store_ent(stash, pkg_key, (SV*)glob, 0)) {
83 1           SvREFCNT_dec_NN(glob);
84 1           croak("Couldn't add a glob to package");
85             }
86             }
87             }
88              
89 190           return glob;
90             }
91              
92             #endif /* __INHERITED_XS_UTIL_H_ */