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
|
|
|
|
|
|
|
} |