diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-09-09 01:59:33 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-09-09 08:47:13 -0700 |
commit | ad39f3a27b57b8caeb757155ed38da916b768bc1 (patch) | |
tree | a3f5c2b03c18db19036c62f6642e3712092054e6 /pp_hot.c | |
parent | da4b417be87225fdd8306a157367330012c6b7d4 (diff) | |
download | perl-ad39f3a27b57b8caeb757155ed38da916b768bc1.tar.gz |
Make &xsub and goto &xsub work with tied @_
This is the only place where tied @_ does not work, and there appears
to be no reason why it shouldn’t, apart from the fact that it hasn’t
been implemented.
Commit 67955e0c was what made &xsub work to begin with. 93965878572
introduced tied arrays and added the comment to pp_entersub saying
that @_ is not tiable.
goto &xsub has worked since perl 5.000, but 93965878572 did not make
it work with tied arrays.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -2715,17 +2715,26 @@ try_autoload: * switch stack to @_, and copy return values * back. This would allow popping @_ in XSUB, e.g.. XXXX */ AV * const av = GvAV(PL_defgv); - const SSize_t items = AvFILLp(av) + 1; /* @_ is not tieable */ + const SSize_t items = AvFILL(av) + 1; if (items) { SSize_t i = 0; + const bool m = cBOOL(SvRMAGICAL(av)); /* Mark is at the end of the stack. */ EXTEND(SP, items); for (; i < items; ++i) - if (AvARRAY(av)[i]) SP[i+1] = AvARRAY(av)[i]; + { + SV *sv; + if (m) { + SV ** const svp = av_fetch(av, i, 0); + sv = svp ? *svp : NULL; + } + else sv = AvARRAY(av)[i]; + if (sv) SP[i+1] = sv; else { SP[i+1] = newSVavdefelem(av, i, 1); } + } SP += items; PUTBACK ; } |