diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-11-23 14:25:22 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-11-30 11:48:37 -0800 |
commit | 9b7476d7a269a4d9bb24393ae5c8d75efe2fcab4 (patch) | |
tree | 61d730354c865de902a488e7255e91ee90685438 /ext/B | |
parent | 6bb83edb7efd3e3c04f6411141538655410c83a4 (diff) | |
download | perl-9b7476d7a269a4d9bb24393ae5c8d75efe2fcab4.tar.gz |
Make PADNAMELIST a separate type
This is in preparation for making PADNAME a separate type.
Diffstat (limited to 'ext/B')
-rw-r--r-- | ext/B/B.pm | 32 | ||||
-rw-r--r-- | ext/B/B.xs | 61 | ||||
-rw-r--r-- | ext/B/typemap | 13 |
3 files changed, 97 insertions, 9 deletions
diff --git a/ext/B/B.pm b/ext/B/B.pm index 01db20d48c..48b830302e 100644 --- a/ext/B/B.pm +++ b/ext/B/B.pm @@ -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 @@ -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 diff --git a/ext/B/B.xs b/ext/B/B.xs index a26c1c9f0b..def00a0de8 100644 --- a/ext/B/B.xs +++ b/ext/B/B.xs @@ -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) \ @@ -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])); } @@ -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) @@ -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 diff --git a/ext/B/typemap b/ext/B/typemap index e97fb76d94..9bb2ed3216 100644 --- a/ext/B/typemap +++ b/ext/B/typemap @@ -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 @@ -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)); @@ -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)); |