summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-08-26 22:28:52 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-08-26 22:28:52 -0700
commit17008668bc1759e4a1ff55f42c3d738e5534b5dc (patch)
treeaf43fc270c8f831d82cf727d09f859085d3b61fa /pp.c
parentcb85b2dba9dd71becf505fd4190513a7648f1ff8 (diff)
downloadperl-17008668bc1759e4a1ff55f42c3d738e5534b5dc.tar.gz
&CORE::foo() for (sys)read and recv
These are grouped together because they all have \$ in their prototypes. This commit allows the subs in the CORE package under those names to be called through references and via &ampersand syntax. The coreargs op in the subroutine is marked with the OPpSCALARMOD flag. (scalar_mod_type in op.c returns true for these three ops, indicating that the OA_SCALARREF parameter is \$, not \[$@%(&)*].) pp_coreargs uses that flag to decide what arguments to reject.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/pp.c b/pp.c
index fe2c4ab389..8ea7eb57d8 100644
--- a/pp.c
+++ b/pp.c
@@ -6114,17 +6114,28 @@ PP(pp_coreargs)
}
break;
case OA_SCALARREF:
+ {
+ const bool wantscalar =
+ PL_op->op_private & OPpCOREARGS_SCALARMOD;
if (!svp || !*svp || !SvROK(*svp)
- || SvTYPE(SvRV(*svp)) > SVt_PVCV
+ /* We have to permit globrefs even for the \$ proto, as
+ *foo is indistinguishable from ${\*foo}, and the proto-
+ type permits the latter. */
+ || SvTYPE(SvRV(*svp)) > (
+ wantscalar ? SVt_PVLV : SVt_PVCV
+ )
)
DIE(aTHX_
/* diag_listed_as: Type of arg %d to &CORE::%s must be %s*/
- "Type of arg %d to &CORE::%s must be reference to one of "
- "[$@%%&*]",
- whicharg, OP_DESC(PL_op->op_next)
+ "Type of arg %d to &CORE::%s must be %s",
+ whicharg, OP_DESC(PL_op->op_next),
+ wantscalar
+ ? "scalar reference"
+ : "reference to one of [$@%&*]"
);
PUSHs(SvRV(*svp));
break;
+ }
default:
DIE(aTHX_ "panic: unknown OA_*: %x", (unsigned)(oa&7));
}