summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-08-25 14:33:03 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-08-25 14:33:03 -0700
commitbf0571fdfef93e57e5d288048145a1610dd40938 (patch)
tree14ef3a17b36cd36d65289dd4a85e1fd7713b823e /pp.c
parent0b19d81a098d6a9b895996d374ca0adc621f1590 (diff)
downloadperl-bf0571fdfef93e57e5d288048145a1610dd40938.tar.gz
&CORE::foo() for @ and $@ prototypes, except unlink
This commit allows the CORE subroutines for functions with @ and $@ prototypes to be called through references and via amper- sand syntax. unlink is not included in this commit, as it requires special casing due to its use of implicit $_. Since these functions require a pushmark, and since it has to come between two things that pp_coreargs does, it’s easiest to flag the coreargs op (with the OPpCOREARGS_PUSHMARK flag added in the previous commit) and call pp_pushmark directly from pp_coreargs.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/pp.c b/pp.c
index 7cffe23aa2..19ba8bc5df 100644
--- a/pp.c
+++ b/pp.c
@@ -6021,6 +6021,7 @@ PP(pp_coreargs)
/* Count how many args there are first, to get some idea how far to
extend the stack. */
while (oa) {
+ if ((oa & 7) == OA_LIST) { maxargs = I32_MAX; break; }
maxargs++;
if (oa & OA_OPTIONAL) seen_question = 1;
if (!seen_question) minargs++;
@@ -6045,7 +6046,15 @@ PP(pp_coreargs)
if(!maxargs) RETURN;
- EXTEND(SP, maxargs);
+ /* We do this here, rather than with a separate pushmark op, as it has
+ to come in between two things this function does (stack reset and
+ arg pushing). This seems the easiest way to do it. */
+ if (PL_op->op_private & OPpCOREARGS_PUSHMARK) {
+ PUTBACK;
+ (void)Perl_pp_pushmark(aTHX);
+ }
+
+ EXTEND(SP, maxargs == I32_MAX ? numargs : maxargs);
PUTBACK; /* The code below can die in various places. */
oa = PL_opargs[opnum] >> OASHIFT;
@@ -6069,6 +6078,12 @@ PP(pp_coreargs)
case OA_SCALAR:
PUSHs(numargs ? svp && *svp ? *svp : &PL_sv_undef : NULL);
break;
+ case OA_LIST:
+ while (numargs--) {
+ PUSHs(svp && *svp ? *svp : &PL_sv_undef);
+ svp++;
+ }
+ RETURN;
case OA_FILEREF:
if(svp && *svp && SvROK(*svp) && isGV_with_GP(SvRV(*svp)))
/* no magic here, as the prototype will have added an extra