69
* if (exists $PL_modglobal{$key}{$package}) {
70
* return $PL_modglobal{$key}{$package};
72
* elsif ($autovivify) {
73
* return $PL_modglobal{$key}{$package} = [];
76
* return $Nullav; # a null pointer in C of course :)
53
79
static AV *modperl_perl_global_avcv_fetch(pTHX_ modperl_modglobal_key_t *gkey,
54
const char *package, I32 packlen)
80
const char *package, I32 packlen,
56
83
HE *he = MP_MODGLOBAL_FETCH(gkey);
59
86
if (!(he && (hv = (HV*)HeVAL(he)))) {
63
if (!(he = hv_fetch_he(hv, (char *)package, packlen, 0))) {
67
return (AV*)HeVAL(he);
88
hv = MP_MODGLOBAL_STORE_HV(gkey);
95
if ((he = hv_fetch_he(hv, (char *)package, packlen, 0))) {
96
return (AV*)HeVAL(he);
100
return (AV*)*hv_store(hv, package, packlen, (SV*)newAV(), 0);
108
/* autovivify $PL_modglobal{$key}{$package} if it doesn't exist yet,
109
* so that in modperl_perl_global_avcv_set we will know whether to
110
* store blocks in it or keep them in the original list.
112
* For example in the case of END blocks, if
113
* $PL_modglobal{END}{$package} exists, modperl_perl_global_avcv_set
114
* will push newly encountered END blocks to it, otherwise it'll keep
117
void modperl_perl_global_avcv_register(pTHX_ modperl_modglobal_key_t *gkey,
118
const char *package, I32 packlen)
120
AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey,
121
package, packlen, TRUE);
123
MP_TRACE_g(MP_FUNC, "register PL_modglobal %s::%s (has %d entries)",
124
package, (char*)gkey->name, av ? 1+av_len(av) : 0);
127
/* if (exists $PL_modglobal{$key}{$package}) {
128
* for my $cv (@{ $PL_modglobal{$key}{$package} }) {
70
133
void modperl_perl_global_avcv_call(pTHX_ modperl_modglobal_key_t *gkey,
71
134
const char *package, I32 packlen)
73
AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen);
136
AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen,
139
MP_TRACE_g(MP_FUNC, "run PL_modglobal %s::%s (has %d entries)",
140
package, (char*)gkey->name, av ? 1+av_len(av) : 0);
143
modperl_perl_call_list(aTHX_ av, gkey->name);
79
modperl_perl_call_list(aTHX_ av, gkey->name);
148
/* if (exists $PL_modglobal{$key}{$package}) {
149
* @{ $PL_modglobal{$key}{$package} } = ();
82
152
void modperl_perl_global_avcv_clear(pTHX_ modperl_modglobal_key_t *gkey,
83
153
const char *package, I32 packlen)
85
AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen);
155
AV *av = modperl_perl_global_avcv_fetch(aTHX_ gkey,
156
package, packlen, FALSE);
158
MP_TRACE_g(MP_FUNC, "clear PL_modglobal %s::%s (has %d entries)",
159
package, (char*)gkey->name, av ? 1+av_len(av) : 0);
94
166
static int modperl_perl_global_avcv_set(pTHX_ SV *sv, MAGIC *mg)
98
168
AV *mav, *av = (AV*)sv;
99
169
const char *package = HvNAME(PL_curstash);
100
170
I32 packlen = strlen(package);
101
171
modperl_modglobal_key_t *gkey =
102
172
(modperl_modglobal_key_t *)mg->mg_ptr;
104
if ((he = MP_MODGLOBAL_FETCH(gkey))) {
108
hv = MP_MODGLOBAL_STORE_HV(gkey);
111
if ((he = hv_fetch_he(hv, (char *)package, packlen, 0))) {
112
mav = (AV*)HeVAL(he);
115
mav = (AV*)*hv_store(hv, package, packlen, (SV*)newAV(), 0);
119
sv = AvARRAY(av)[AvFILLp(av)];
120
AvARRAY(av)[AvFILLp(av)--] = &PL_sv_undef;
174
/* the argument sv, is the original list perl was operating on.
175
* (e.g. PL_endav). So now if we find that we have package/cv name
176
* (e.g. Foo/END) registered for set-aside, we remove the cv that
177
* was just unshifted in and push it into
178
* $PL_modglobal{$key}{$package}. Otherwise we do nothing, which
179
* keeps the unshifted cv (e.g. END block) in its original av
183
mav = modperl_perl_global_avcv_fetch(aTHX_ gkey, package, packlen, FALSE);
186
MP_TRACE_g(MP_FUNC, "%s::%s is not going to PL_modglobal",
187
package, (char*)gkey->name);
188
/* keep it in the tied list (e.g. PL_endav) */
192
MP_TRACE_g(MP_FUNC, "%s::%s is going into PL_modglobal",
193
package, (char*)gkey->name);
122
197
/* push @{ $PL_modglobal{$key}{$package} }, $cv */
123
av_store(mav, AvFILLp(av)+1, sv);
198
av_store(mav, AvFILLp(mav)+1, sv);
200
/* print scalar @{ $PL_modglobal{$key}{$package} } */
201
MP_TRACE_g(MP_FUNC, "%s::%s av now has %d entries\n",
202
package, (char*)gkey->name, 1+av_len(mav));