File Coverage

Var.xs
Criterion Covered Total %
statement 193 206 93.6
branch 106 144 73.6
condition n/a
subroutine n/a
pod n/a
total 299 350 85.4


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT 1
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
7             #define PERL_DECIMAL_VERSION \
8             PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
9             #define PERL_VERSION_GE(r,v,s) \
10             (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
11              
12             #if !PERL_VERSION_GE(5,9,3)
13             # define SVt_LAST (SVt_PVIO+1)
14             #endif /* <5.9.3 */
15              
16             #if PERL_VERSION_GE(5,9,4)
17             # define SVt_PADNAME SVt_PVMG
18             #else /* <5.9.4 */
19             # define SVt_PADNAME SVt_PVGV
20             #endif /* <5.9.4 */
21              
22             #ifndef sv_setpvs
23             # define sv_setpvs(SV, STR) sv_setpvn(SV, ""STR"", sizeof(STR)-1)
24             #endif /* !sv_setpvs */
25              
26             #ifndef gv_stashpvs
27             # define gv_stashpvs(name, flags) gv_stashpvn(""name"", sizeof(name)-1, flags)
28             #endif /* !gv_stashpvs */
29              
30             #ifndef SvPAD_OUR_on
31             # define SvPAD_OUR_on(SV) (SvFLAGS(SV) |= SVpad_OUR)
32             #endif /* !SvPAD_OUR_on */
33              
34             #ifndef SvOURSTASH_set
35             # ifdef OURSTASH_set
36             # define SvOURSTASH_set(SV, STASH) OURSTASH_set(SV, STASH)
37             # else /* !OURSTASH_set */
38             # define SvOURSTASH_set(SV, STASH) (GvSTASH(SV) = STASH)
39             # endif /* !OURSTASH_set */
40             #endif /* !SvOURSTASH_set */
41              
42             #ifndef PadMAX
43             # define PadlistARRAY(pl) ((PAD**)AvARRAY(pl))
44             # define PadlistNAMES(pl) (PadlistARRAY(pl)[0])
45             # define PadMAX(p) AvFILLp(p)
46             typedef AV PADNAMELIST;
47             #endif /* !PadMAX */
48              
49             #if !PERL_VERSION_GE(5,8,1)
50             typedef AV PADLIST;
51             typedef AV PAD;
52             #endif /* <5.8.1 */
53              
54             #ifndef COP_SEQ_RANGE_LOW
55             # if PERL_VERSION_GE(5,9,5)
56             # define COP_SEQ_RANGE_LOW(sv) ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xlow
57             # define COP_SEQ_RANGE_HIGH(sv) ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh
58             # else /* <5.9.5 */
59             # define COP_SEQ_RANGE_LOW(sv) ((U32)SvNVX(sv))
60             # define COP_SEQ_RANGE_HIGH(sv) ((U32)SvIVX(sv))
61             # endif /* <5.9.5 */
62             #endif /* !COP_SEQ_RANGE_LOW */
63              
64             #ifndef COP_SEQ_RANGE_LOW_set
65             # ifdef newPADNAMEpvn
66             # define COP_SEQ_RANGE_LOW_set(sv,val) \
67             do { (sv)->xpadn_low = (val); } while(0)
68             # define COP_SEQ_RANGE_HIGH_set(sv,val) \
69             do { (sv)->xpadn_high = (val); } while(0)
70             # elif PERL_VERSION_GE(5,9,5)
71             # define COP_SEQ_RANGE_LOW_set(sv,val) \
72             do { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xlow = val; } while(0)
73             # define COP_SEQ_RANGE_HIGH_set(sv,val) \
74             do { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh = val; } while(0)
75             # else /* <5.9.5 */
76             # define COP_SEQ_RANGE_LOW_set(sv,val) SvNV_set(sv, val)
77             # define COP_SEQ_RANGE_HIGH_set(sv,val) SvIV_set(sv, val)
78             # endif /* <5.9.5 */
79             #endif /* !COP_SEQ_RANGE_LOW_set */
80              
81             #ifndef SvRV_set
82             # define SvRV_set(SV, VAL) (SvRV(SV) = (VAL))
83             #endif /* !SvRV_set */
84              
85             #ifndef newSV_type
86             # define newSV_type(type) THX_newSV_type(aTHX_ type)
87             static SV *THX_newSV_type(pTHX_ svtype type)
88             {
89             SV *sv = newSV(0);
90             (void) SvUPGRADE(sv, type);
91             return sv;
92             }
93             #endif /* !newSV_type */
94              
95             #ifndef SVfARG
96             # define SVfARG(p) ((void *)p)
97             #endif /* !SVfARG */
98              
99             #ifndef GV_NOTQUAL
100             # define GV_NOTQUAL 0
101             #endif /* !GV_NOTQUAL */
102              
103             #ifndef padnamelist_store
104             /* Note that the return values are different. If we ever call it in non-
105             void context, we would have to change it to *av_store. */
106             # define padnamelist_store av_store
107             #endif
108              
109             /*
110             * scalar classification
111             *
112             * Logic borrowed from Params::Classify.
113             */
114              
115             #define sv_is_glob(sv) (SvTYPE(sv) == SVt_PVGV)
116              
117             #if PERL_VERSION_GE(5,11,0)
118             # define sv_is_regexp(sv) (SvTYPE(sv) == SVt_REGEXP)
119             #else /* <5.11.0 */
120             # define sv_is_regexp(sv) 0
121             #endif /* <5.11.0 */
122              
123             #define sv_is_string(sv) \
124             (!sv_is_glob(sv) && !sv_is_regexp(sv) && \
125             (SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK|SVp_IOK|SVp_NOK|SVp_POK)))
126              
127             /*
128             * gen_const_identity_op()
129             *
130             * This function generate op that evaluates to a fixed object identity
131             * and can also participate in constant folding.
132             *
133             * Lexical::Var generally needs to make ops that evaluate to fixed
134             * identities, that being what a name that it handles represents.
135             * Normally it can do this by means of an rv2xv op applied to a const op,
136             * where the const op holds an RV that references the object of interest.
137             * However, rv2xv can't undergo constant folding. Where the object is
138             * a readonly scalar, we'd like it to take part in constant folding.
139             * The obvious way to make it work as a constant for folding is to use a
140             * const op that directly holds the object. However, in a Perl built for
141             * ithreads, the value in a const op gets moved into the pad to achieve
142             * clonability, and in the process the value may be copied rather than the
143             * object merely rereferenced. Generally, the const op only guarantees
144             * to provide a fixed *value*, not a fixed object identity.
145             *
146             * Where a const op might not preserve object identity, we can achieve
147             * preservation by means of a customised variant of the const op. The op
148             * directly holds an RV that references the object of interest, and its
149             * variant pp function dereferences it (as rv2sv would). The pad logic
150             * operates on the op structure as normal, and may copy the RV without
151             * preserving its identity, which is OK because the RV isn't what we
152             * need to preserve. Being labelled as a const op, it is eligible for
153             * constant folding. When actually executed, it evaluates to the object
154             * of interest, providing both fixed value and fixed identity.
155             */
156              
157             #ifdef USE_ITHREADS
158             # define Q_USE_ITHREADS 1
159             #else /* !USE_ITHREADS */
160             # define Q_USE_ITHREADS 0
161             #endif /* !USE_ITHREADS */
162              
163             #define Q_CONST_COPIES Q_USE_ITHREADS
164              
165             #if Q_CONST_COPIES
166             static OP *pp_const_via_ref(pTHX)
167             {
168             dSP;
169             SV *reference_sv = cSVOPx_sv(PL_op);
170             SV *referent_sv = SvRV(reference_sv);
171             PUSHs(referent_sv);
172             RETURN;
173             }
174             #endif /* Q_CONST_COPIES */
175              
176             #define gen_const_identity_op(sv) THX_gen_const_identity_op(aTHX_ sv)
177 30           static OP *THX_gen_const_identity_op(pTHX_ SV *sv)
178             {
179             #if Q_CONST_COPIES
180             OP *op = newSVOP(OP_CONST, 0, newRV_noinc(sv));
181             op->op_ppaddr = pp_const_via_ref;
182             return op;
183             #else /* !Q_CONST_COPIES */
184 30           return newSVOP(OP_CONST, 0, sv);
185             #endif /* !Q_CONST_COPIES */
186             }
187              
188             /*
189             * %^H key names
190             */
191              
192             #define KEYPREFIX "Lexical::Var/"
193             #define KEYPREFIXLEN (sizeof(KEYPREFIX)-1)
194              
195             #define LEXPADPREFIX "Lexical::Var::"
196             #define LEXPADPREFIXLEN (sizeof(LEXPADPREFIX)-1)
197              
198             #define CHAR_IDSTART 0x01
199             #define CHAR_IDCONT 0x02
200             #define CHAR_SIGIL 0x10
201             #define CHAR_USEPAD 0x20
202              
203             static U8 char_attr[256] = {
204             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* NUL to BEL */
205             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* BS to SI */
206             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* DLE to ETB */
207             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CAN to US */
208             0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x00, /* SP to ' */
209             0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* ( to / */
210             0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 0 to 7 */
211             0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 to ? */
212             0x30, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* @ to G */
213             0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* H to O */
214             0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* P to W */
215             0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, /* X to _ */
216             0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ` to g */
217             0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* h to o */
218             0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* p to w */
219             0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, /* x to DEL */
220             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
221             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
222             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
223             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
224             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
225             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
226             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
227             0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
228             };
229              
230             #define name_key(sigil, name) THX_name_key(aTHX_ sigil, name)
231 11411           static SV *THX_name_key(pTHX_ char sigil, SV *name)
232             {
233             char const *p, *q, *end;
234             STRLEN len;
235             SV *key;
236 11411 50         p = SvPV(name, len);
237 11411           end = p + len;
238 11411 100         if(sigil == 'N') {
239 410           sigil = *p++;
240 410 100         if(!(char_attr[(U8)sigil] & CHAR_SIGIL)) return NULL;
241 11001 100         } else if(sigil == 'P') {
242 7250 100         if(strnNE(p, LEXPADPREFIX, LEXPADPREFIXLEN)) return NULL;
243 165           p += LEXPADPREFIXLEN;
244 165           sigil = *p++;
245 165 50         if(!(char_attr[(U8)sigil] & CHAR_SIGIL)) return NULL;
246 165 50         if(p[0] != ':' || p[1] != ':') return NULL;
    50          
247 165           p += 2;
248             }
249 4321 100         if(!(char_attr[(U8)*p] & CHAR_IDSTART)) return NULL;
250 25599 100         for(q = p+1; q != end; q++) {
251 23061 100         if(!(char_attr[(U8)*q] & CHAR_IDCONT)) return NULL;
252             }
253 2538           key = sv_2mortal(newSV(KEYPREFIXLEN + 1 + (end-p)));
254 2538           sv_setpvs(key, KEYPREFIX"?");
255 2538           SvPVX(key)[KEYPREFIXLEN] = sigil;
256 2538           sv_catpvn(key, p, end-p);
257 11411           return key;
258             }
259              
260             /*
261             * compiling code that uses lexical variables
262             */
263              
264             #define gv_mark_multi(name) THX_gv_mark_multi(aTHX_ name)
265 315           static void THX_gv_mark_multi(pTHX_ SV *name)
266             {
267             GV *gv;
268             #ifdef gv_fetchsv
269 315           gv = gv_fetchsv(name, GV_NOADD_NOINIT|GV_NOEXPAND|GV_NOTQUAL,
270             SVt_PVGV);
271             #else /* !gv_fetchsv */
272             gv = gv_fetchpv(SvPVX(name), 0, SVt_PVGV);
273             #endif /* !gv_fetchsv */
274 315 100         if(gv && SvTYPE(gv) == SVt_PVGV) GvMULTI_on(gv);
    50          
275 315           }
276              
277             static SV *fake_sv, *fake_av, *fake_hv;
278              
279             #define ck_rv2xv(o, sigil, nxck) THX_ck_rv2xv(aTHX_ o, sigil, nxck)
280 18173           static OP *THX_ck_rv2xv(pTHX_ OP *o, char sigil, OP *(*nxck)(pTHX_ OP *o))
281             {
282             OP *c;
283             SV *ref, *key;
284             HE *he;
285 18173 50         if((o->op_flags & OPf_KIDS) && (c = cUNOPx(o)->op_first) &&
    50          
    100          
286 11301 100         c->op_type == OP_CONST &&
287 10851 50         (c->op_private & (OPpCONST_ENTERED|OPpCONST_BARE)) &&
288 10851 50         (ref = cSVOPx(c)->op_sv) && SvPOK(ref) &&
    100          
289 10851           (key = name_key(sigil, ref))) {
290 2001 100         if((he = hv_fetch_ent(GvHV(PL_hintgv), key, 0, 0))) {
291             SV *hintref, *referent, *fake_referent, *newref;
292             OP *newop;
293             U16 type, flags;
294             #if !PERL_VERSION_GE(5,11,2)
295             if(sigil == '&' && (c->op_private & OPpCONST_BARE))
296             croak("can't reference lexical subroutine "
297             "without & sigil on this perl");
298             #endif /* <5.11.2 */
299 474 100         if(sigil != 'P' || !PERL_VERSION_GE(5,8,0)) {
300             /*
301             * A bogus symbol lookup has already been
302             * done (by the tokeniser) based on the name
303             * we're using, to support the package-based
304             * interpretation that we're about to
305             * replace. This can cause bogus "used only
306             * once" warnings. The best we can do here
307             * is to flag the symbol as multiply-used to
308             * suppress that warning, though this is at
309             * the risk of muffling an accurate warning.
310             */
311 315           gv_mark_multi(ref);
312             }
313             /*
314             * The base checker for rv2Xv checks that the
315             * item being pointed to by the constant ref is of
316             * an appropriate type. There are two problems with
317             * this check. Firstly, it rejects GVs as a scalar
318             * target, whereas they are in fact valid. (This
319             * is in RT as bug #69456 so may be fixed.) Second,
320             * and more serious, sometimes a reference is being
321             * constructed through the wrong op type. An array
322             * indexing expression "$foo[0]" gets constructed as
323             * an rv2sv op, because of the "$" sigil, and then
324             * gets munged later. We have to detect the real
325             * intended type through the pad entry, which the
326             * tokeniser has worked out in advance, and then
327             * work through the wrong op. So it's a bit cheeky
328             * for perl to complain about the wrong type here.
329             * We work around it by making the constant ref
330             * initially point to an innocuous item to pass the
331             * type check, then changing it to the real
332             * reference later.
333             */
334 474           hintref = HeVAL(he);
335 474 50         if(!SvROK(hintref))
336 0           croak("non-reference hint for Lexical::Var");
337 474           referent = SvREFCNT_inc(SvRV(hintref));
338 474           type = o->op_type;
339 474           flags = o->op_flags | (((U16)o->op_private) << 8);
340 474 100         if(type == OP_RV2SV && sigil == 'P' &&
    50          
    100          
341 102 100         SvPVX(ref)[LEXPADPREFIXLEN] == '$' &&
342 102           SvREADONLY(referent)) {
343 30           op_free(o);
344 30           return gen_const_identity_op(referent);
345             }
346 444           switch(type) {
347 80           case OP_RV2SV: fake_referent = fake_sv; break;
348 28           case OP_RV2AV: fake_referent = fake_av; break;
349 21           case OP_RV2HV: fake_referent = fake_hv; break;
350 315           default: fake_referent = referent; break;
351             }
352 444           newref = newRV_noinc(fake_referent);
353 444 100         if(referent != fake_referent) {
354 129           SvREFCNT_inc(fake_referent);
355 129           SvREFCNT_inc(newref);
356             }
357 444           newop = newUNOP(type, flags,
358             newSVOP(OP_CONST, 0, newref));
359 444 100         if(referent != fake_referent) {
360 129           fake_referent = SvRV(newref);
361 129           SvREADONLY_off(newref);
362 129           SvRV_set(newref, referent);
363 129           SvREADONLY_on(newref);
364 129           SvREFCNT_dec(fake_referent);
365 129           SvREFCNT_dec(newref);
366             }
367 444           op_free(o);
368 444           return newop;
369 1527 100         } else if(sigil == 'P') {
370             SV *newref;
371             U16 type, flags;
372             /*
373             * Not a name that we have a defined meaning for,
374             * but it has the form of the "our" hack, implying
375             * that we did put an entry in the pad for it.
376             * Munge this back to what it would have been
377             * without the pad entry. This should mainly
378             * happen due to explicit unimportation, but it
379             * might also happen if the scoping of the pad and
380             * %^H ever get out of synch.
381             */
382 6           newref = newSVpvn(SvPVX(ref)+LEXPADPREFIXLEN+3,
383             SvCUR(ref)-LEXPADPREFIXLEN-3);
384 6 50         if(SvUTF8(ref)) SvUTF8_on(newref);
385 6           type = o->op_type;
386 6           flags = o->op_flags | (((U16)o->op_private) << 8);
387 6           op_free(o);
388 6           return newUNOP(type, flags,
389             newSVOP(OP_CONST, 0, newref));
390             }
391             }
392 17693           return nxck(aTHX_ o);
393             }
394              
395             static OP *(*nxck_rv2sv)(pTHX_ OP *o);
396             static OP *(*nxck_rv2av)(pTHX_ OP *o);
397             static OP *(*nxck_rv2hv)(pTHX_ OP *o);
398             static OP *(*nxck_rv2cv)(pTHX_ OP *o);
399             static OP *(*nxck_rv2gv)(pTHX_ OP *o);
400              
401 11194           static OP *ck_rv2sv(pTHX_ OP *o) { return ck_rv2xv(o, 'P', nxck_rv2sv); }
402 5190           static OP *ck_rv2av(pTHX_ OP *o) { return ck_rv2xv(o, 'P', nxck_rv2av); }
403 11628           static OP *ck_rv2hv(pTHX_ OP *o) { return ck_rv2xv(o, 'P', nxck_rv2hv); }
404 7738           static OP *ck_rv2cv(pTHX_ OP *o) { return ck_rv2xv(o, '&', nxck_rv2cv); }
405 596           static OP *ck_rv2gv(pTHX_ OP *o) { return ck_rv2xv(o, '*', nxck_rv2gv); }
406              
407             /*
408             * setting up lexical names
409             */
410              
411             static HV *stash_lex_sv, *stash_lex_av, *stash_lex_hv;
412              
413             #define pad_max() THX_pad_max(aTHX)
414 166           static U32 THX_pad_max(pTHX)
415             {
416             #if PERL_VERSION_GE(5,13,10)
417 166           return U32_MAX;
418             #elif PERL_VERSION_GE(5,9,5)
419             return I32_MAX;
420             #elif PERL_VERSION_GE(5,9,0)
421             return 999999999;
422             #elif PERL_VERSION_GE(5,8,0)
423             static U32 max;
424             if(!max) {
425             SV *versv = get_sv("]", 0);
426             char *verp = SvPV_nolen(versv);
427             max = strGE(verp, "5.008009") ? I32_MAX : 999999999;
428             }
429             return max;
430             #else /* <5.8.0 */
431             return 999999999;
432             #endif /* <5.8.0 */
433             }
434              
435             #define find_compcv(vari_word) THX_find_compcv(aTHX_ vari_word)
436 574           static CV *THX_find_compcv(pTHX_ char const *vari_word)
437             {
438             CV *compcv;
439             #if PERL_VERSION_GE(5,17,5)
440 574 100         if(!((compcv = PL_compcv) && CvPADLIST(compcv)))
    50          
441 2           compcv = NULL;
442             #else /* <5.17.5 */
443             GV *compgv;
444             /*
445             * Given that we're being invoked from a BEGIN block,
446             * PL_compcv here doesn't actually point to the sub
447             * being compiled. Instead it points to the BEGIN block.
448             * The code that we want to affect is the parent of that.
449             * Along the way, better check that we are actually being
450             * invoked that way: PL_compcv may be null, indicating
451             * runtime, or it can be non-null in a couple of
452             * other situations (require, string eval).
453             */
454             if(!(PL_compcv && CvSPECIAL(PL_compcv) &&
455             (compgv = CvGV(PL_compcv)) &&
456             strEQ(GvNAME(compgv), "BEGIN") &&
457             (compcv = CvOUTSIDE(PL_compcv)) &&
458             CvPADLIST(compcv)))
459             compcv = NULL;
460             #endif /* <5.17.5 */
461 574 100         if(!compcv)
462 2           croak("can't set up lexical %s outside compilation",
463             vari_word);
464 572           return compcv;
465             }
466              
467             #define setup_pad(compcv, name) THX_setup_pad(aTHX_ compcv, name)
468 166           static void THX_setup_pad(pTHX_ CV *compcv, char const *name)
469             {
470 166           PADLIST *padlist = CvPADLIST(compcv);
471 166           PADNAMELIST *padname = PadlistNAMES(padlist);
472 166           PAD *padvar = PadlistARRAY(padlist)[1];
473             PADOFFSET ouroffset;
474             PADNAME *ourname;
475             SV *ourvar;
476             HV *stash;
477 166           ourvar = *av_fetch(padvar, PadMAX(padvar) + 1, 1);
478 166           SvPADMY_on(ourvar);
479 166           ouroffset = PadMAX(padvar);
480             #ifdef newPADNAMEpvn
481 166           ourname = newPADNAMEpvn(name, strlen(name));
482             #else
483             ourname = newSV_type(SVt_PADNAME);
484             sv_setpv(ourname, name);
485             #endif
486 166           SvPAD_OUR_on(ourname);
487 219 100         stash = name[0] == '$' ? stash_lex_sv :
488 53 100         name[0] == '@' ? stash_lex_av : stash_lex_hv;
489 166           SvOURSTASH_set(ourname, (HV*)SvREFCNT_inc((SV*)stash));
490 166           COP_SEQ_RANGE_LOW_set(ourname, PL_cop_seqmax);
491 166           COP_SEQ_RANGE_HIGH_set(ourname, pad_max());
492 166           PL_cop_seqmax++;
493 166           padnamelist_store(padname, ouroffset, ourname);
494             #ifdef PadnamelistMAXNAMED
495 166           PadnamelistMAXNAMED(padname) = ouroffset;
496             #endif /* PadnamelistMAXNAMED */
497 166           }
498              
499             #define lookup_for_compilation(base_sigil, vari_word, name) \
500             THX_lookup_for_compilation(aTHX_ base_sigil, vari_word, name)
501 0           static SV *THX_lookup_for_compilation(pTHX_ char base_sigil,
502             char const *vari_word, SV *name)
503             {
504             SV *key;
505             HE *he;
506 0 0         if(!sv_is_string(name)) croak("%s name is not a string", vari_word);
    0          
    0          
507 0           key = name_key(base_sigil, name);
508 0 0         if(!key) croak("malformed %s name", vari_word);
509 0           he = hv_fetch_ent(GvHV(PL_hintgv), key, 0, 0);
510 0 0         return he ? SvREFCNT_inc(HeVAL(he)) : &PL_sv_undef;
511             }
512              
513 111           static int svt_scalar(svtype t)
514             {
515 111 100         switch(t) {
516             case SVt_NULL: case SVt_IV: case SVt_NV:
517             #if !PERL_VERSION_GE(5,11,0)
518             case SVt_RV:
519             #endif /* <5.11.0 */
520             case SVt_PV: case SVt_PVIV: case SVt_PVNV:
521             case SVt_PVMG: case SVt_PVLV: case SVt_PVGV:
522             #if PERL_VERSION_GE(5,11,0)
523             case SVt_REGEXP:
524             #endif /* >=5.11.0 */
525 104           return 1;
526             default:
527 7           return 0;
528             }
529             }
530              
531             #define import(base_sigil, vari_word) THX_import(aTHX_ base_sigil, vari_word)
532 539           static void THX_import(pTHX_ char base_sigil, char const *vari_word)
533             {
534 539           dXSARGS;
535             CV *compcv;
536             int i;
537 539           SP -= items;
538 539 50         if(items < 1)
539 0           croak("too few arguments for import");
540 539 100         if(items == 1)
541 4           croak("%"SVf" does no default importation", SVfARG(ST(0)));
542 535 100         if(!(items & 1))
543 4           croak("import list for %"SVf
544 4           " must alternate name and reference", SVfARG(ST(0)));
545 531           compcv = find_compcv(vari_word);
546 530           PL_hints |= HINT_LOCALIZE_HH;
547 530           gv_HVadd(PL_hintgv);
548 962 100         for(i = 1; i != items; i += 2) {
549 530           SV *name = ST(i), *ref = ST(i+1), *key, *val;
550             svtype rt;
551             bool rok;
552             char const *vt;
553             char sigil;
554             HE *he;
555 530 50         if(!sv_is_string(name))
    50          
    100          
556 6           croak("%s name is not a string", vari_word);
557 524           key = name_key(base_sigil, name);
558 524 100         if(!key) croak("malformed %s name", vari_word);
559 510           sigil = SvPVX(key)[KEYPREFIXLEN];
560 510 100         rt = SvROK(ref) ? SvTYPE(SvRV(ref)) : SVt_LAST;
561 510           switch(sigil) {
562 111           case '$': rok = svt_scalar(rt); vt="scalar"; break;
563 41           case '@': rok = rt == SVt_PVAV; vt="array"; break;
564 40           case '%': rok = rt == SVt_PVHV; vt="hash"; break;
565 283           case '&': rok = rt == SVt_PVCV; vt="code"; break;
566 35           case '*': rok = rt == SVt_PVGV; vt="glob"; break;
567 0           default: rok = 0; vt = "wibble"; break;
568             }
569 510 100         if(!rok) croak("%s is not %s reference", vari_word, vt);
570 432           val = newRV_inc(SvRV(ref));
571 432           he = hv_store_ent(GvHV(PL_hintgv), key, val, 0);
572 432 50         if(he) {
573 432           val = HeVAL(he);
574 432 50         SvSETMAGIC(val);
575             } else {
576 0           SvREFCNT_dec(val);
577             }
578 432 100         if(char_attr[(U8)sigil] & CHAR_USEPAD)
579 157           setup_pad(compcv, SvPVX(key)+KEYPREFIXLEN);
580             }
581 432           PUTBACK;
582 432           }
583              
584             #define unimport(base_sigil, vari_word) \
585             THX_unimport(aTHX_ base_sigil, vari_word)
586 47           static void THX_unimport(pTHX_ char base_sigil, char const *vari_word)
587             {
588 47           dXSARGS;
589             CV *compcv;
590             int i;
591 47           SP -= items;
592 47 50         if(items < 1)
593 0           croak("too few arguments for unimport");
594 47 100         if(items == 1)
595 4           croak("%"SVf" does no default unimportation", SVfARG(ST(0)));
596 43           compcv = find_compcv(vari_word);
597 42           PL_hints |= HINT_LOCALIZE_HH;
598 42           gv_HVadd(PL_hintgv);
599 69 100         for(i = 1; i != items; i++) {
600 42           SV *name = ST(i), *ref, *key;
601             char sigil;
602 42 50         if(!sv_is_string(name))
    50          
    100          
603 6           croak("%s name is not a string", vari_word);
604 36           key = name_key(base_sigil, name);
605 36 100         if(!key) croak("malformed %s name", vari_word);
606 27           sigil = SvPVX(key)[KEYPREFIXLEN];
607 27 50         if(i != items && (ref = ST(i+1), SvROK(ref))) {
    100          
608             HE *he;
609             SV *cref;
610 13           i++;
611 13           he = hv_fetch_ent(GvHV(PL_hintgv), key, 0, 0);
612 13 50         cref = he ? HeVAL(he) : &PL_sv_undef;
613 13 50         if(SvROK(cref) && SvRV(cref) != SvRV(ref))
    100          
614 6           continue;
615             }
616 21           (void) hv_delete_ent(GvHV(PL_hintgv), key, G_DISCARD, 0);
617 21 100         if(char_attr[(U8)sigil] & CHAR_USEPAD)
618 9           setup_pad(compcv, SvPVX(key)+KEYPREFIXLEN);
619             }
620 27           }
621              
622             MODULE = Lexical::Var PACKAGE = Lexical::Var
623              
624             PROTOTYPES: DISABLE
625              
626             BOOT:
627 35           fake_sv = &PL_sv_undef;
628 35           fake_av = (SV*)newAV();
629 35           fake_hv = (SV*)newHV();
630 35           stash_lex_sv = gv_stashpvs(LEXPADPREFIX"$", 1);
631 35           stash_lex_av = gv_stashpvs(LEXPADPREFIX"@", 1);
632 35           stash_lex_hv = gv_stashpvs(LEXPADPREFIX"%", 1);
633 35           nxck_rv2sv = PL_check[OP_RV2SV]; PL_check[OP_RV2SV] = ck_rv2sv;
634 35           nxck_rv2av = PL_check[OP_RV2AV]; PL_check[OP_RV2AV] = ck_rv2av;
635 35           nxck_rv2hv = PL_check[OP_RV2HV]; PL_check[OP_RV2HV] = ck_rv2hv;
636 35           nxck_rv2cv = PL_check[OP_RV2CV]; PL_check[OP_RV2CV] = ck_rv2cv;
637 35           nxck_rv2gv = PL_check[OP_RV2GV]; PL_check[OP_RV2GV] = ck_rv2gv;
638              
639             SV *
640             _variable_for_compilation(SV *classname, SV *name)
641             CODE:
642             PERL_UNUSED_VAR(classname);
643 0           RETVAL = lookup_for_compilation('N', "variable", name);
644             OUTPUT:
645             RETVAL
646              
647             void
648             import(SV *classname, ...)
649             PPCODE:
650             PERL_UNUSED_VAR(classname);
651 392 50         PUSHMARK(SP);
652             /* the modified SP is intentionally lost here */
653 392           import('N', "variable");
654 313           SPAGAIN;
655              
656             void
657             unimport(SV *classname, ...)
658             PPCODE:
659             PERL_UNUSED_VAR(classname);
660 32 50         PUSHMARK(SP);
661             /* the modified SP is intentionally lost here */
662 32           unimport('N', "variable");
663 21           SPAGAIN;
664              
665             MODULE = Lexical::Var PACKAGE = Lexical::Sub
666              
667             SV *
668             _sub_for_compilation(SV *classname, SV *name)
669             CODE:
670             PERL_UNUSED_VAR(classname);
671 0           RETVAL = lookup_for_compilation('&', "subroutine", name);
672             OUTPUT:
673             RETVAL
674              
675             void
676             import(SV *classname, ...)
677             PPCODE:
678             PERL_UNUSED_VAR(classname);
679 147 50         PUSHMARK(SP);
680             /* the modified SP is intentionally lost here */
681 147           import('&', "subroutine");
682 119           SPAGAIN;
683              
684             void
685             unimport(SV *classname, ...)
686             PPCODE:
687             PERL_UNUSED_VAR(classname);
688 15 50         PUSHMARK(SP);
689             /* the modified SP is intentionally lost here */
690 15           unimport('&', "subroutine");
691 6           SPAGAIN;