summaryrefslogtreecommitdiff
path: root/ext/B
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-11-23 14:25:22 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-11-30 11:48:37 -0800
commit9b7476d7a269a4d9bb24393ae5c8d75efe2fcab4 (patch)
tree61d730354c865de902a488e7255e91ee90685438 /ext/B
parent6bb83edb7efd3e3c04f6411141538655410c83a4 (diff)
downloadperl-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.pm32
-rw-r--r--ext/B/B.xs61
-rw-r--r--ext/B/typemap13
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));