summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorFelipe Gasper <felipe@felipegasper.com>2022-09-12 08:58:00 -0400
committerTony Cook <tony@develop-help.com>2022-10-10 08:47:18 +1100
commit35458d36d3c9fcf47064e4379e15276057b0bca5 (patch)
tree1a70bc5af2d2b264d4bbbf2006669609538db68c /op.c
parenta37e8492a204a8885d9d7e6526c9ef1a1902690f (diff)
downloadperl-35458d36d3c9fcf47064e4379e15276057b0bca5.tar.gz
Compile anonymous subs as anoncode without srefgen.
Heretofore the compiler represented an anonymous subroutine as an anoncode op then an srefgen op; the latter’s only purpose was to return a reference to the anoncode’s returned CV. This changeset slightly optimizes that by making pp_anoncode return a reference if so bidden. The same optimization is applied to pp_anonconst as well. Deparse.pm is updated accordingly.
Diffstat (limited to 'op.c')
-rw-r--r--op.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/op.c b/op.c
index b54399192b..0d56fdf5e5 100644
--- a/op.c
+++ b/op.c
@@ -7220,7 +7220,6 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor)
* pushmark (for regcomp)
* pushmark (for entersub)
* anoncode
- * srefgen
* entersub
* regcreset regcreset
* pushmark pushmark
@@ -7234,10 +7233,9 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor)
SvREFCNT_inc_simple_void(PL_compcv);
CvLVALUE_on(PL_compcv);
/* these lines are just an unrolled newANONATTRSUB */
- expr = newSVOP(OP_ANONCODE, 0,
+ expr = newSVOP(OP_ANONCODE, OPf_REF,
MUTABLE_SV(newATTRSUB(floor, 0, NULL, NULL, expr)));
cv_targ = expr->op_targ;
- expr = newUNOP(OP_REFGEN, 0, expr);
expr = list(force_list(newUNOP(OP_ENTERSUB, 0, scalar(expr)), TRUE));
}
@@ -11365,15 +11363,21 @@ OP *
Perl_newANONATTRSUB(pTHX_ I32 floor, OP *proto, OP *attrs, OP *block)
{
SV * const cv = MUTABLE_SV(newATTRSUB(floor, 0, proto, attrs, block));
+
+ bool is_const = CvANONCONST(cv);
+
OP * anoncode =
- newSVOP(OP_ANONCODE, 0,
+ newSVOP(OP_ANONCODE, is_const ? 0 : OPf_REF,
cv);
- if (CvANONCONST(cv))
- anoncode = newUNOP(OP_ANONCONST, 0,
+
+ if (is_const) {
+ anoncode = newUNOP(OP_ANONCONST, OPf_REF,
op_convert_list(OP_ENTERSUB,
OPf_STACKED|OPf_WANT_SCALAR,
anoncode));
- return newUNOP(OP_REFGEN, 0, anoncode);
+ }
+
+ return anoncode;
}
OP *
@@ -13745,6 +13749,7 @@ Perl_ck_entersub_args_proto(pTHX_ OP *entersubop, GV *namegv, SV *protosv)
proto++;
arg++;
if ( o3->op_type != OP_UNDEF
+ && o3->op_type != OP_ANONCODE
&& (o3->op_type != OP_SREFGEN
|| ( cUNOPx(cUNOPx(o3)->op_first)->op_first->op_type
!= OP_ANONCODE