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