Skip to content

Commit

Permalink
Make PADNAMELIST a separate type
Browse files Browse the repository at this point in the history
This is in preparation for making PADNAME a separate type.
  • Loading branch information
Father Chrysostomos committed Nov 30, 2014
1 parent 6bb83ed commit 9b7476d
Show file tree
Hide file tree
Showing 15 changed files with 355 additions and 106 deletions.
2 changes: 0 additions & 2 deletions av.h
Expand Up @@ -73,8 +73,6 @@ Same as C<av_top_index()>.
#define AvREIFY_on(av) (SvFLAGS(av) |= SVpav_REIFY)
#define AvREIFY_off(av) (SvFLAGS(av) &= ~SVpav_REIFY)
#define AvREIFY_only(av) (AvREAL_off(av), SvFLAGS(av) |= SVpav_REIFY)
#define AvPAD_NAMELIST(av) (SvFLAGS(av) & SVpad_NAMELIST)
#define AvPAD_NAMELIST_on(av) (SvFLAGS(av) |= SVpad_NAMELIST)


#define AvREALISH(av) (SvFLAGS(av) & (SVpav_REAL|SVpav_REIFY))
Expand Down
15 changes: 4 additions & 11 deletions dump.c
Expand Up @@ -1496,7 +1496,6 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
if (SvPAD_STATE(sv)) sv_catpv(d, "STATE,");
goto evaled_or_uv;
case SVt_PVAV:
if (AvPAD_NAMELIST(sv)) sv_catpvs(d, "NAMELIST,");
break;
}
/* SVphv_SHAREKEYS is also 0x20000000 */
Expand Down Expand Up @@ -1643,9 +1642,6 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
HV * const ost = SvOURSTASH(sv);
if (ost)
do_hv_dump(level, file, " OURSTASH", ost);
} else if (SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv)) {
Perl_dump_indent(aTHX_ level, file, " MAXNAMED = %"UVuf"\n",
(UV)PadnamelistMAXNAMED(sv));
} else {
if (SvMAGIC(sv))
do_magic_dump(level, file, SvMAGIC(sv), nest+1, maxnest, dumpops, pvlim);
Expand All @@ -1671,10 +1667,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
PerlIO_putc(file, '\n');
Perl_dump_indent(aTHX_ level, file, " FILL = %"IVdf"\n", (IV)AvFILLp(sv));
Perl_dump_indent(aTHX_ level, file, " MAX = %"IVdf"\n", (IV)AvMAX(sv));
/* arylen is stored in magic, and padnamelists use SvMAGIC for
something else. */
if (!AvPAD_NAMELIST(sv))
Perl_dump_indent(aTHX_ level, file, " ARYLEN = 0x%"UVxf"\n",
Perl_dump_indent(aTHX_ level, file, " ARYLEN = 0x%"UVxf"\n",
SvMAGIC(sv) ? PTR2UV(AvARYLEN(sv)) : 0);
sv_setpvs(d, "");
if (AvREAL(sv)) sv_catpv(d, ",REAL");
Expand Down Expand Up @@ -2303,17 +2296,17 @@ Perl_debop(pTHX_ const OP *o)
{
CV * const cv = deb_curcv(cxstack_ix);
SV *sv;
PAD * comppad = NULL;
PADNAMELIST * comppad = NULL;
int i;

if (cv) {
PADLIST * const padlist = CvPADLIST(cv);
comppad = *PadlistARRAY(padlist);
comppad = PadlistNAMES(padlist);
}
PerlIO_printf(Perl_debug_log, "(");
for (i = 0; i < count; i++) {
if (comppad &&
(sv = *av_fetch(comppad, o->op_targ + i, FALSE)))
(sv = padnamelist_fetch(comppad, o->op_targ + i)))
PerlIO_printf(Perl_debug_log, "%s", SvPV_nolen_const(sv));
else
PerlIO_printf(Perl_debug_log, "[%"UVuf"]",
Expand Down
7 changes: 7 additions & 0 deletions embed.fnc
Expand Up @@ -1000,6 +1000,7 @@ AmdbR |HV* |newHV
ApaR |HV* |newHVhv |NULLOK HV *hv
Apabm |IO* |newIO
Apda |OP* |newLISTOP |I32 type|I32 flags|NULLOK OP* first|NULLOK OP* last
AMpda |PADNAMELIST *|newPADNAMELIST|size_t max
#ifdef USE_ITHREADS
Apda |OP* |newPADOP |I32 type|I32 flags|NN SV* sv
#endif
Expand Down Expand Up @@ -2583,7 +2584,13 @@ p |CV* |cv_clone_into |NN CV* proto|NN CV *target
pd |void |pad_fixup_inner_anons|NN PADLIST *padlist|NN CV *old_cv|NN CV *new_cv
pdX |void |pad_push |NN PADLIST *padlist|int depth
ApbdR |HV* |pad_compname_type|const PADOFFSET po
AMpdR |PADNAME *|padnamelist_fetch|NN PADNAMELIST *pnl|SSize_t key
Xop |void |padnamelist_free|NN PADNAMELIST *pnl
AMpd |PADNAME **|padnamelist_store|NN PADNAMELIST *pnl|SSize_t key \
|NULLOK PADNAME *val
#if defined(USE_ITHREADS)
pR |PADNAMELIST *|padnamelist_dup|NN PADNAMELIST *srcpad \
|NN CLONE_PARAMS *param
pdR |PADLIST *|padlist_dup |NN PADLIST *srcpad \
|NN CLONE_PARAMS *param
#endif
Expand Down
4 changes: 4 additions & 0 deletions embed.h
Expand Up @@ -384,6 +384,7 @@
#define newMYSUB(a,b,c,d,e) Perl_newMYSUB(aTHX_ a,b,c,d,e)
#define newNULLLIST() Perl_newNULLLIST(aTHX)
#define newOP(a,b) Perl_newOP(aTHX_ a,b)
#define newPADNAMELIST(a) Perl_newPADNAMELIST(aTHX_ a)
#define newPMOP(a,b) Perl_newPMOP(aTHX_ a,b)
#define newPROG(a) Perl_newPROG(aTHX_ a)
#define newPVOP(a,b,c) Perl_newPVOP(aTHX_ a,b,c)
Expand Down Expand Up @@ -449,6 +450,8 @@
#define pad_findmy_sv(a,b) Perl_pad_findmy_sv(aTHX_ a,b)
#define pad_new(a) Perl_pad_new(aTHX_ a)
#define pad_tidy(a) Perl_pad_tidy(aTHX_ a)
#define padnamelist_fetch(a,b) Perl_padnamelist_fetch(aTHX_ a,b)
#define padnamelist_store(a,b,c) Perl_padnamelist_store(aTHX_ a,b,c)
#define parse_arithexpr(a) Perl_parse_arithexpr(aTHX_ a)
#define parse_barestmt(a) Perl_parse_barestmt(aTHX_ a)
#define parse_block(a) Perl_parse_block(aTHX_ a)
Expand Down Expand Up @@ -1755,6 +1758,7 @@
# if defined(USE_ITHREADS)
#define mro_meta_dup(a,b) Perl_mro_meta_dup(aTHX_ a,b)
#define padlist_dup(a,b) Perl_padlist_dup(aTHX_ a,b)
#define padnamelist_dup(a,b) Perl_padnamelist_dup(aTHX_ a,b)
# endif
# if defined(USE_LOCALE) && (defined(PERL_IN_LOCALE_C) || defined (PERL_EXT_POSIX))
#define stdize_locale(a) S_stdize_locale(aTHX_ a)
Expand Down
32 changes: 28 additions & 4 deletions ext/B/B.pm
Expand Up @@ -1296,11 +1296,13 @@ Since perl 5.17.1
=back
=head2 OTHER CLASSES
=head2 PAD-RELATED CLASSES
Perl 5.18 introduces a new class, B::PADLIST, returned by B::CV's
Perl 5.18 introduced a new class, B::PADLIST, returned by B::CV's
C<PADLIST> method.
Perl 5.22 introduced the B::PADNAMELIST and B::PADNAME classes.
=head2 B::PADLIST Methods
=over 4
Expand All @@ -1309,14 +1311,36 @@ C<PADLIST> method.
=item ARRAY
A list of pads. The first one contains the names. These are currently
B::AV objects, but that is likely to change in future versions.
A list of pads. The first one contains the names.
The first one is a B::PADNAMELIST under Perl 5.22, and a B::AV under
earlier versions. The rest are currently B::AV objects, but that could
change in future versions.
=item ARRAYelt
Like C<ARRAY>, but takes an index as an argument to get only one element,
rather than a list of all of them.
=item NAMES
This method, introduced in 5.22, returns the B::PADNAMELIST. It is
equivalent to C<ARRAYelt> with a 0 argument.
=item REFCNT
=back
=head2 B::PADNAMELIST Methods
=over 4
=item MAX
=item ARRAY
=item ARRAYelt
=item REFCNT
=back
Expand Down
61 changes: 56 additions & 5 deletions ext/B/B.xs
Expand Up @@ -620,6 +620,8 @@ typedef struct refcounted_he *B__RHE;
#ifdef PadlistARRAY
typedef PADLIST *B__PADLIST;
#endif
typedef PADNAMELIST *B__PADNAMELIST;


#ifdef MULTIPLICITY
# define ASSIGN_COMMON_ALIAS(prefix, var) \
Expand Down Expand Up @@ -2059,15 +2061,31 @@ MODULE = B PACKAGE = B::PADLIST PREFIX = Padlist
SSize_t
PadlistMAX(padlist)
B::PADLIST padlist
ALIAS: B::PADNAMELIST::MAX = 0
CODE:
PERL_UNUSED_VAR(ix);
RETVAL = PadlistMAX(padlist);
OUTPUT:
RETVAL

B::PADNAMELIST
PadlistNAMES(padlist)
B::PADLIST padlist

void
PadlistARRAY(padlist)
B::PADLIST padlist
PPCODE:
if (PadlistMAX(padlist) >= 0) {
dXSTARG;
PAD **padp = PadlistARRAY(padlist);
SSize_t i;
for (i = 0; i <= PadlistMAX(padlist); i++)
sv_setiv(newSVrv(TARG, PadlistNAMES(padlist)
? "B::PADNAMELIST"
: "B::NULL"),
PTR2IV(PadlistNAMES(padlist)));
XPUSHTARG;
for (i = 1; i <= PadlistMAX(padlist); i++)
XPUSHs(make_sv_object(aTHX_ (SV *)padp[i]));
}

Expand All @@ -2076,12 +2094,17 @@ PadlistARRAYelt(padlist, idx)
B::PADLIST padlist
SSize_t idx
PPCODE:
if (PadlistMAX(padlist) >= 0
&& idx <= PadlistMAX(padlist))
if (idx < 0 || idx > PadlistMAX(padlist))
XPUSHs(make_sv_object(aTHX_ NULL));
else if (!idx) {
PL_stack_sp--;
PUSHMARK(PL_stack_sp-1);
XS_B__PADLIST_NAMES(aTHX_ cv);
return;
}
else
XPUSHs(make_sv_object(aTHX_
(SV *)PadlistARRAY(padlist)[idx]));
else
XPUSHs(make_sv_object(aTHX_ NULL));

U32
PadlistREFCNT(padlist)
Expand All @@ -2093,3 +2116,31 @@ PadlistREFCNT(padlist)
RETVAL

#endif

MODULE = B PACKAGE = B::PADNAMELIST PREFIX = Padnamelist

void
PadnamelistARRAY(pnl)
B::PADNAMELIST pnl
PPCODE:
if (PadnamelistMAX(pnl) >= 0) {
PADNAME **padp = PadnamelistARRAY(pnl);
SSize_t i = 0;
for (; i <= PadnamelistMAX(pnl); i++)
XPUSHs(make_sv_object(aTHX_ padp[i]));
}

void
PadnamelistARRAYelt(pnl, idx)
B::PADNAMELIST pnl
SSize_t idx
PPCODE:
if (idx < 0 || idx > PadnamelistMAX(pnl))
XPUSHs(make_sv_object(aTHX_ NULL));
else
XPUSHs(make_sv_object(aTHX_
(SV *)PadnamelistARRAY(pnl)[idx]));

U32
PadnamelistREFCNT(pnl)
B::PADNAMELIST pnl
13 changes: 13 additions & 0 deletions ext/B/typemap
Expand Up @@ -37,6 +37,7 @@ B::HE T_HE_OBJ
B::RHE T_RHE_OBJ

B::PADLIST T_PL_OBJ
B::PADNAMELIST T_PNL_OBJ

INPUT
T_OP_OBJ
Expand Down Expand Up @@ -87,6 +88,14 @@ T_PL_OBJ
else
croak(\"$var is not a reference\")

T_PNL_OBJ
if (SvROK($arg)) {
IV tmp = SvIV((SV*)SvRV($arg));
$var = INT2PTR($type,tmp);
}
else
croak(\"$var is not a reference\")

OUTPUT
T_MG_OBJ
sv_setiv(newSVrv($arg, "B::MAGIC"), PTR2IV($var));
Expand All @@ -100,3 +109,7 @@ T_RHE_OBJ
T_PL_OBJ
sv_setiv(newSVrv($arg, $var ? "B::PADLIST" : "B::NULL"),
PTR2IV($var));

T_PNL_OBJ
sv_setiv(newSVrv($arg, $var ? "B::PADNAMELIST" : "B::NULL"),
PTR2IV($var));
2 changes: 0 additions & 2 deletions mg.c
Expand Up @@ -390,8 +390,6 @@ S_mg_findext_flags(const SV *sv, int type, const MGVTBL *vtbl, U32 flags)
if (sv) {
MAGIC *mg;

assert(!(SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv)));

for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
if (mg->mg_type == type && (!flags || mg->mg_virtual == vtbl)) {
return mg;
Expand Down
2 changes: 1 addition & 1 deletion op.c
Expand Up @@ -2295,7 +2295,7 @@ S_finalize_op(pTHX_ OP* o)

check_fields =
rop
&& (lexname = *av_fetch(PL_comppad_name, rop->op_targ, TRUE),
&& (lexname = padnamelist_fetch(PL_comppad_name, rop->op_targ),
SvPAD_TYPED(lexname))
&& (fields = (GV**)hv_fetchs(SvSTASH(lexname), "FIELDS", FALSE))
&& isGV(*fields) && GvHV(*fields);
Expand Down

0 comments on commit 9b7476d

Please sign in to comment.