The SVs in the names AV have their PV being the name of the variable.
NV+1..IV inclusive is a range of cop_seq numbers for which the name is
valid. For typed lexicals name SV is SVt_PVMG and SvSTASH points at the
-type. For C<our> lexicals, the type is also SVt_PVGV, with the MAGIC slot
+type. For C<our> lexicals, the type is also SVt_PVMG, with the OURSTASH slot
pointing at the stash of the associated global (so that duplicate C<our>
declarations in the same package can be detected). SvCUR is sometimes
hijacked to store the generation number during compilation.
#include "EXTERN.h"
#define PERL_IN_PAD_C
#include "perl.h"
+#include "keywords.h"
#define PAD_MAX 999999999
*/
PADOFFSET
-Perl_pad_add_name(pTHX_ const char *name, HV* typestash, HV* ourstash, bool fake)
+Perl_pad_add_name(pTHX_ const char *name, HV* typestash, HV* ourstash, bool fake, bool state)
{
dVAR;
const PADOFFSET offset = pad_alloc(OP_PADSV, SVs_PADMY);
sv_setpv(namesv, name);
if (typestash) {
+ assert(SvTYPE(namesv) == SVt_PVMG);
SvPAD_TYPED_on(namesv);
SvSTASH_set(namesv, (HV*)SvREFCNT_inc_simple_NN((SV*)typestash));
}
OURSTASH_set(namesv, ourstash);
SvREFCNT_inc_simple_void_NN(ourstash);
}
+ else if (state) {
+ SvPAD_STATE_on(namesv);
+ }
av_store(PL_comppad_name, offset, namesv);
if (fake) {
break; /* "our" masking "our" */
Perl_warner(aTHX_ packWARN(WARN_MISC),
"\"%s\" variable %s masks earlier declaration in same %s",
- (is_our ? "our" : "my"),
+ (is_our ? "our" : PL_in_my == KEY_my ? "my" : "state"),
name,
(SvIVX(sv) == PAD_MAX ? "scope" : "statement"));
--off;
SV **name_svp;
pad_peg("pad_findmy");
- offset = pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
+ offset = pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
NULL, &out_sv, &out_flags);
- if (offset != NOT_IN_PAD)
+ if ((PADOFFSET)offset != NOT_IN_PAD)
return offset;
/* look for an our that's being introduced; this allows
if (!CvOUTSIDE(cv))
return NOT_IN_PAD;
-
+
/* out_capture non-null means caller wants us to capture lex; in
* addition we capture ourselves unless it's an ANON/format */
new_capturep = out_capture ? out_capture :
offset = pad_findlex(name, CvOUTSIDE(cv), CvOUTSIDE_SEQ(cv), 1,
new_capturep, out_name_sv, out_flags);
- if (offset == NOT_IN_PAD)
+ if ((PADOFFSET)offset == NOT_IN_PAD)
return NOT_IN_PAD;
-
+
/* found in an outer CV. Add appropriate fake entry to this pad */
/* don't add new fake entries (via eval) to CVs that we have already
SvPAD_TYPED(*out_name_sv)
? SvSTASH(*out_name_sv) : NULL,
OURSTASH(*out_name_sv),
- 1 /* fake */
+ 1, /* fake */
+ 0 /* not a state variable */
);
new_namesv = AvARRAY(PL_comppad_name)[new_offset];
SvNV_set(new_namesv, (NV)0);
if (SvPAD_OUR(new_namesv)) {
- /*EMPTY*/; /* do nothing */
+ NOOP; /* do nothing */
}
else if (CvLATE(cv)) {
/* delayed creation - just note the offset within parent pad */
if (sv && sv != &PL_sv_undef
&& !SvFAKE(sv) && ckWARN_d(WARN_INTERNAL))
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
- "%"SVf" never introduced", sv);
+ "%"SVf" never introduced",
+ (void*)sv);
}
}
/* "Deintroduce" my variables that are leaving with this scope. */