Commit 93c691b8a6 for perl

commit 93c691b8a6c32a3223371c82b46e29a16ef500f2
Author: Branislav Zahradník <barney@cpan.org>
Date:   Sun Sep 27 17:06:18 2026 +0200

    [perly] function invocation -> Action build_function_invocation

    - using arguments in `code, arguments` order
    - hiding less important implementation details

diff --git a/embed.fnc b/embed.fnc
index 2500994b78..f5adf0858a 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1015,6 +1015,10 @@ p	|void	|boot_core_mro
 p	|void	|boot_core_PerlIO
 : Used in perl.c
 p	|void	|boot_core_UNIVERSAL
+dp	|OP *	|build_function_invocation				\
+				|I32 flags				\
+				|NN OP *code				\
+				|NULLOK OP *arguments
 p	|OP *	|build_infix_plugin					\
 				|NN OP *lhs				\
 				|NN OP *rhs				\
diff --git a/embed.h b/embed.h
index 3b51c4558c..3bf7d416da 100644
--- a/embed.h
+++ b/embed.h
@@ -1003,6 +1003,7 @@
 #   define boot_core_UNIVERSAL()                Perl_boot_core_UNIVERSAL(aTHX)
 #   define boot_core_builtin()                  Perl_boot_core_builtin(aTHX)
 #   define boot_core_mro()                      Perl_boot_core_mro(aTHX)
+#   define build_function_invocation(a,b,c)     Perl_build_function_invocation(aTHX_ a,b,c)
 #   define build_infix_plugin(a,b,c)            Perl_build_infix_plugin(aTHX_ a,b,c)
 #   define build_method_invocation(a,b,c)       Perl_build_method_invocation(aTHX_ a,b,c)
 #   define build_method_invocation_arguments(a,b) Perl_build_method_invocation_arguments(aTHX_ a,b)
diff --git a/op.c b/op.c
index 2f6f535db5..31ee49cc1f 100644
--- a/op.c
+++ b/op.c
@@ -4892,6 +4892,29 @@ Perl_block_end(pTHX_ I32 floor, OP *seq)
     return retval;
 }

+/*
+=for apidoc build_function_invocation
+
+    build_function_invocation (flags, $function, $arguments);
+    build_function_invocation (flags, $function, NULL);
+
+Available since: v5.46
+
+=cut
+*/
+
+OP*
+Perl_build_function_invocation (pTHX_ I32 flags, OP *code, OP *arguments)
+{
+    PERL_ARGS_ASSERT_BUILD_FUNCTION_INVOCATION;
+
+    return newUNOP (
+        OP_ENTERSUB,
+        flags,
+        op_append_elem (OP_LIST, arguments, code)
+    );
+}
+
 /*
 =for apidoc build_method_invocation

diff --git a/perly.act b/perly.act
index bbfefe22a3..1a74bb335d 100644
--- a/perly.act
+++ b/perly.act
@@ -1326,17 +1326,13 @@ case 2: /* @1: %empty  */
   case 204: /* listop: LSTOPSUB startanonsub block @24 optlistexpr  */
 #line 1436 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
+					(ps[-4].val.opval),
+					op_prepend_elem (
 						OP_LIST,
-						op_prepend_elem (
-							OP_LIST,
-							(ps[-1].val.opval),
-							(ps[0].val.opval)
-						),
-						(ps[-4].val.opval)
+						(ps[-1].val.opval),
+						(ps[0].val.opval)
 					)
 				);
 			}
@@ -1344,20 +1340,20 @@ case 2: /* @1: %empty  */
     break;

   case 207: /* subscripted: gelem subscript_keys  */
-#line 1462 "perly.y"
+#line 1458 "perly.y"
                         { (yyval.opval) = newBINOP(OP_GELEM, 0, (ps[-1].val.opval), scalar((ps[0].val.opval))); }

     break;

   case 208: /* subscripted: scalar subscript_index  */
-#line 1464 "perly.y"
+#line 1460 "perly.y"
                         { (yyval.opval) = newBINOP(OP_AELEM, 0, oopsAV((ps[-1].val.opval)), scalar((ps[0].val.opval)));
 			}

     break;

   case 209: /* subscripted: subscriptable_reference subscript_index  */
-#line 1467 "perly.y"
+#line 1463 "perly.y"
                         { (yyval.opval) = newBINOP(OP_AELEM, 0,
 					ref(newAVREF((ps[-1].val.opval)),OP_RV2AV),
 					scalar((ps[0].val.opval)));
@@ -1366,14 +1362,14 @@ case 2: /* @1: %empty  */
     break;

   case 210: /* subscripted: scalar subscript_keys  */
-#line 1472 "perly.y"
+#line 1468 "perly.y"
                         { (yyval.opval) = newBINOP(OP_HELEM, 0, oopsHV((ps[-1].val.opval)), jmaybe((ps[0].val.opval)));
 			}

     break;

   case 211: /* subscripted: subscriptable_reference subscript_keys  */
-#line 1475 "perly.y"
+#line 1471 "perly.y"
                         { (yyval.opval) = newBINOP(OP_HELEM, 0,
 					ref(newHVREF((ps[-1].val.opval)),OP_RV2HV),
 					jmaybe((ps[0].val.opval))); }
@@ -1381,16 +1377,12 @@ case 2: /* @1: %empty  */
     break;

   case 212: /* subscripted: subscriptable_reference PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE  */
-#line 1483 "perly.y"
+#line 1479 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						(ps[-1].val.opval),
-						newCVREF (0, scalar ((ps[-3].val.opval)))
-					)
+					newCVREF (0, scalar ((ps[-3].val.opval))),
+					(ps[-1].val.opval)
 				);
 				if (parser->expect == XBLOCK)
 					parser->expect = XOPERATOR;
@@ -1399,12 +1391,12 @@ case 2: /* @1: %empty  */
     break;

   case 213: /* subscripted: subscriptable_reference PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1500 "perly.y"
+#line 1492 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					newCVREF (0, scalar((ps[-2].val.opval)))
+					newCVREF (0, scalar ((ps[-2].val.opval))),
+					NULL
 				);
 				if (parser->expect == XBLOCK)
 					parser->expect = XOPERATOR;
@@ -1413,55 +1405,55 @@ case 2: /* @1: %empty  */
     break;

   case 214: /* subscripted: PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE subscript_index  */
-#line 1510 "perly.y"
+#line 1502 "perly.y"
                         { (yyval.opval) = newSLICEOP(0, (ps[0].val.opval), (ps[-2].val.opval)); }

     break;

   case 215: /* subscripted: QWLIST subscript_index  */
-#line 1512 "perly.y"
+#line 1504 "perly.y"
                         { (yyval.opval) = newSLICEOP(0, (ps[0].val.opval), (ps[-1].val.opval)); }

     break;

   case 216: /* subscripted: PERLY_PAREN_OPEN PERLY_PAREN_CLOSE subscript_index  */
-#line 1514 "perly.y"
+#line 1506 "perly.y"
                         { (yyval.opval) = newSLICEOP(0, (ps[0].val.opval), NULL); }

     break;

   case 217: /* termbinop: term PLUGIN_HIGH_OP term  */
-#line 1519 "perly.y"
+#line 1511 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 218: /* termbinop: term ASSIGNOP term  */
-#line 1521 "perly.y"
+#line 1513 "perly.y"
                         { (yyval.opval) = newASSIGNOP(OPf_STACKED, (ps[-2].val.opval), (ps[-1].val.ival), (ps[0].val.opval)); }

     break;

   case 219: /* termbinop: term PLUGIN_ASSIGN_OP term  */
-#line 1523 "perly.y"
+#line 1515 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 220: /* termbinop: term POWOP term  */
-#line 1525 "perly.y"
+#line 1517 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 221: /* termbinop: term PLUGIN_POW_OP term  */
-#line 1527 "perly.y"
+#line 1519 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 222: /* termbinop: term MULOP term  */
-#line 1529 "perly.y"
+#line 1521 "perly.y"
                         {   if ((ps[-1].val.ival) != OP_REPEAT)
 				scalar((ps[-2].val.opval));
 			    (yyval.opval) = newBINOP((ps[-1].val.ival), 0, (ps[-2].val.opval), scalar((ps[0].val.opval)));
@@ -1470,219 +1462,219 @@ case 2: /* @1: %empty  */
     break;

   case 223: /* termbinop: term PLUGIN_MUL_OP term  */
-#line 1534 "perly.y"
+#line 1526 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 224: /* termbinop: term ADDOP term  */
-#line 1536 "perly.y"
+#line 1528 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 225: /* termbinop: term PLUGIN_ADD_OP term  */
-#line 1538 "perly.y"
+#line 1530 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 226: /* termbinop: term SHIFTOP term  */
-#line 1540 "perly.y"
+#line 1532 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 227: /* termbinop: termrelop  */
-#line 1542 "perly.y"
+#line 1534 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 228: /* termbinop: termeqop  */
-#line 1544 "perly.y"
+#line 1536 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 229: /* termbinop: term BITANDOP term  */
-#line 1546 "perly.y"
+#line 1538 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 230: /* termbinop: term BITOROP term  */
-#line 1548 "perly.y"
+#line 1540 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 231: /* termbinop: term DOTDOT term  */
-#line 1550 "perly.y"
+#line 1542 "perly.y"
                         { (yyval.opval) = newRANGE((ps[-1].val.ival), scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 232: /* termbinop: term ANDAND term  */
-#line 1552 "perly.y"
+#line 1544 "perly.y"
                         { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 233: /* termbinop: term PLUGIN_LOGICAL_AND_OP term  */
-#line 1554 "perly.y"
+#line 1546 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 234: /* termbinop: term OROR term  */
-#line 1556 "perly.y"
+#line 1548 "perly.y"
                         { (yyval.opval) = newLOGOP((ps[-1].val.ival), 0, (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 235: /* termbinop: term PLUGIN_LOGICAL_OR_OP term  */
-#line 1558 "perly.y"
+#line 1550 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 236: /* termbinop: term DORDOR term  */
-#line 1560 "perly.y"
+#line 1552 "perly.y"
                         { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 237: /* termbinop: term MATCHOP term  */
-#line 1562 "perly.y"
+#line 1554 "perly.y"
                         { (yyval.opval) = bind_match((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 238: /* termbinop: term PLUGIN_LOW_OP term  */
-#line 1564 "perly.y"
+#line 1556 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 239: /* termrelop: relopchain  */
-#line 1568 "perly.y"
+#line 1560 "perly.y"
                         { (yyval.opval) = cmpchain_finish((ps[0].val.opval)); }

     break;

   case 240: /* termrelop: term NCRELOP term  */
-#line 1570 "perly.y"
+#line 1562 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 241: /* termrelop: termrelop NCRELOP  */
-#line 1572 "perly.y"
+#line 1564 "perly.y"
                         { yyerror("syntax error"); YYERROR; }

     break;

   case 242: /* termrelop: termrelop CHRELOP  */
-#line 1574 "perly.y"
+#line 1566 "perly.y"
                         { yyerror("syntax error"); YYERROR; }

     break;

   case 243: /* termrelop: term PLUGIN_REL_OP term  */
-#line 1576 "perly.y"
+#line 1568 "perly.y"
                         { (yyval.opval) = build_infix_plugin((ps[-2].val.opval), (ps[0].val.opval), (ps[-1].val.pval)); }

     break;

   case 244: /* relopchain: term CHRELOP term  */
-#line 1580 "perly.y"
+#line 1572 "perly.y"
                         { (yyval.opval) = cmpchain_start((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 245: /* relopchain: relopchain CHRELOP term  */
-#line 1582 "perly.y"
+#line 1574 "perly.y"
                         { (yyval.opval) = cmpchain_extend((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 246: /* termeqop: eqopchain  */
-#line 1586 "perly.y"
+#line 1578 "perly.y"
                         { (yyval.opval) = cmpchain_finish((ps[0].val.opval)); }

     break;

   case 247: /* termeqop: term NCEQOP term  */
-#line 1588 "perly.y"
+#line 1580 "perly.y"
                         { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }

     break;

   case 248: /* termeqop: termeqop NCEQOP  */
-#line 1590 "perly.y"
+#line 1582 "perly.y"
                         { yyerror("syntax error"); YYERROR; }

     break;

   case 249: /* termeqop: termeqop CHEQOP  */
-#line 1592 "perly.y"
+#line 1584 "perly.y"
                         { yyerror("syntax error"); YYERROR; }

     break;

   case 250: /* eqopchain: term CHEQOP term  */
-#line 1596 "perly.y"
+#line 1588 "perly.y"
                         { (yyval.opval) = cmpchain_start((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 251: /* eqopchain: eqopchain CHEQOP term  */
-#line 1598 "perly.y"
+#line 1590 "perly.y"
                         { (yyval.opval) = cmpchain_extend((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 252: /* termunop: PERLY_MINUS term  */
-#line 1603 "perly.y"
+#line 1595 "perly.y"
                         { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[0].val.opval))); }

     break;

   case 253: /* termunop: PERLY_PLUS term  */
-#line 1605 "perly.y"
+#line 1597 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 254: /* termunop: PERLY_EXCLAMATION_MARK term  */
-#line 1608 "perly.y"
+#line 1600 "perly.y"
                         { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); }

     break;

   case 255: /* termunop: PERLY_TILDE term  */
-#line 1610 "perly.y"
+#line 1602 "perly.y"
                         { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, scalar((ps[0].val.opval))); }

     break;

   case 256: /* termunop: term POSTINC  */
-#line 1612 "perly.y"
+#line 1604 "perly.y"
                         { (yyval.opval) = newUNOP(OP_POSTINC, 0,
 					op_lvalue(scalar((ps[-1].val.opval)), OP_POSTINC)); }

     break;

   case 257: /* termunop: term POSTDEC  */
-#line 1615 "perly.y"
+#line 1607 "perly.y"
                         { (yyval.opval) = newUNOP(OP_POSTDEC, 0,
 					op_lvalue(scalar((ps[-1].val.opval)), OP_POSTDEC));}

     break;

   case 258: /* termunop: term POSTJOIN  */
-#line 1618 "perly.y"
+#line 1610 "perly.y"
                         { (yyval.opval) = op_convert_list(OP_JOIN, 0,
 				       op_append_elem(
 					OP_LIST,
@@ -1697,59 +1689,59 @@ case 2: /* @1: %empty  */
     break;

   case 259: /* termunop: PREINC term  */
-#line 1629 "perly.y"
+#line 1621 "perly.y"
                         { (yyval.opval) = newUNOP(OP_PREINC, 0,
 					op_lvalue(scalar((ps[0].val.opval)), OP_PREINC)); }

     break;

   case 260: /* termunop: PREDEC term  */
-#line 1632 "perly.y"
+#line 1624 "perly.y"
                         { (yyval.opval) = newUNOP(OP_PREDEC, 0,
 					op_lvalue(scalar((ps[0].val.opval)), OP_PREDEC)); }

     break;

   case 261: /* anonymous: PERLY_BRACKET_OPEN optexpr PERLY_BRACKET_CLOSE  */
-#line 1640 "perly.y"
+#line 1632 "perly.y"
                         { (yyval.opval) = newANONLIST((ps[-1].val.opval)); }

     break;

   case 262: /* anonymous: HASHBRACK optexpr PERLY_SEMICOLON PERLY_BRACE_CLOSE  */
-#line 1642 "perly.y"
+#line 1634 "perly.y"
                         { (yyval.opval) = newANONHASH((ps[-2].val.opval)); }

     break;

   case 263: /* anonymous: KW_SUB_anon startanonsub proto subattrlist subbody  */
-#line 1644 "perly.y"
+#line 1636 "perly.y"
                         { SvREFCNT_inc_simple_void(PL_compcv);
 			  (yyval.opval) = newANONATTRSUB((ps[-3].val.ival), (ps[-2].val.opval), (ps[-1].val.opval), (ps[0].val.opval)); }

     break;

   case 264: /* anonymous: KW_SUB_anon startanonsub proto subattrlist  */
-#line 1647 "perly.y"
+#line 1639 "perly.y"
                         { yyerror("Illegal declaration of anonymous subroutine"); YYERROR; }

     break;

   case 265: /* anonymous: KW_SUB_anon_sig startanonsub subattrlist sigsubbody  */
-#line 1649 "perly.y"
+#line 1641 "perly.y"
                         { SvREFCNT_inc_simple_void(PL_compcv);
 			  (yyval.opval) = newANONATTRSUB((ps[-2].val.ival), NULL, (ps[-1].val.opval), (ps[0].val.opval)); }

     break;

   case 266: /* anonymous: KW_SUB_anon_sig startanonsub subattrlist  */
-#line 1652 "perly.y"
+#line 1644 "perly.y"
                         { yyerror("Illegal declaration of anonymous subroutine"); YYERROR; }

     break;

   case 267: /* anonymous: KW_METHOD_anon startanonmethod subattrlist sigsubbody  */
-#line 1654 "perly.y"
+#line 1646 "perly.y"
                         {
 			  SvREFCNT_inc_simple_void(PL_compcv);
 			  (yyval.opval) = newANONATTRSUB((ps[-2].val.ival), NULL, (ps[-1].val.opval), (ps[0].val.opval));
@@ -1758,103 +1750,103 @@ case 2: /* @1: %empty  */
     break;

   case 268: /* anonymous: KW_METHOD_anon startanonmethod subattrlist  */
-#line 1659 "perly.y"
+#line 1651 "perly.y"
                         { yyerror("Illegal declaration of anonymous subroutine"); YYERROR; }

     break;

   case 269: /* termdo: KW_DO term  */
-#line 1664 "perly.y"
+#line 1656 "perly.y"
                         { (yyval.opval) = dofile((ps[0].val.opval), (ps[-1].val.ival));}

     break;

   case 270: /* termdo: KW_DO block  */
-#line 1666 "perly.y"
+#line 1658 "perly.y"
                         { (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, op_scope((ps[0].val.opval)));}

     break;

   case 275: /* term: term PERLY_QUESTION_MARK term PERLY_COLON term  */
-#line 1674 "perly.y"
+#line 1666 "perly.y"
                         { (yyval.opval) = newCONDOP(0, (ps[-4].val.opval), (ps[-2].val.opval), (ps[0].val.opval)); }

     break;

   case 276: /* term: REFGEN term  */
-#line 1676 "perly.y"
+#line 1668 "perly.y"
                         { (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval)); }

     break;

   case 277: /* term: myattrterm  */
-#line 1678 "perly.y"
+#line 1670 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 278: /* term: KW_LOCAL term  */
-#line 1680 "perly.y"
+#line 1672 "perly.y"
                         { (yyval.opval) = localize((ps[0].val.opval),0); }

     break;

   case 279: /* term: PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE  */
-#line 1682 "perly.y"
+#line 1674 "perly.y"
                         { (yyval.opval) = sawparens((ps[-1].val.opval)); }

     break;

   case 280: /* term: QWLIST  */
-#line 1684 "perly.y"
+#line 1676 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 281: /* term: PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1686 "perly.y"
+#line 1678 "perly.y"
                         { (yyval.opval) = sawparens(newNULLLIST()); }

     break;

   case 282: /* term: scalar  */
-#line 1688 "perly.y"
+#line 1680 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 283: /* term: star  */
-#line 1690 "perly.y"
+#line 1682 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 284: /* term: hsh  */
-#line 1692 "perly.y"
+#line 1684 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 285: /* term: ary  */
-#line 1694 "perly.y"
+#line 1686 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 286: /* term: arylen  */
-#line 1696 "perly.y"
+#line 1688 "perly.y"
                         { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[0].val.opval), OP_AV2ARYLEN));}

     break;

   case 287: /* term: subscripted  */
-#line 1698 "perly.y"
+#line 1690 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 288: /* term: sliceme subscript_index  */
-#line 1700 "perly.y"
+#line 1692 "perly.y"
                         { (yyval.opval) = op_prepend_elem(OP_ASLICE,
 				newOP(OP_PUSHMARK, 0),
 				    newLISTOP(OP_ASLICE, 0,
@@ -1868,7 +1860,7 @@ case 2: /* @1: %empty  */
     break;

   case 289: /* term: kvslice subscript_index  */
-#line 1710 "perly.y"
+#line 1702 "perly.y"
                         { (yyval.opval) = op_prepend_elem(OP_KVASLICE,
 				newOP(OP_PUSHMARK, 0),
 				    newLISTOP(OP_KVASLICE, 0,
@@ -1882,7 +1874,7 @@ case 2: /* @1: %empty  */
     break;

   case 290: /* term: sliceme subscript_keys  */
-#line 1720 "perly.y"
+#line 1712 "perly.y"
                         { (yyval.opval) = op_prepend_elem(OP_HSLICE,
 				newOP(OP_PUSHMARK, 0),
 				    newLISTOP(OP_HSLICE, 0,
@@ -1896,7 +1888,7 @@ case 2: /* @1: %empty  */
     break;

   case 291: /* term: kvslice subscript_keys  */
-#line 1730 "perly.y"
+#line 1722 "perly.y"
                         { (yyval.opval) = op_prepend_elem(OP_KVHSLICE,
 				newOP(OP_PUSHMARK, 0),
 				    newLISTOP(OP_KVHSLICE, 0,
@@ -1910,213 +1902,206 @@ case 2: /* @1: %empty  */
     break;

   case 292: /* term: THING  */
-#line 1740 "perly.y"
+#line 1732 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 293: /* term: amper  */
-#line 1743 "perly.y"
+#line 1735 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					0,
-					scalar ((ps[0].val.opval))
+					scalar ((ps[0].val.opval)),
+					NULL
 				);
 			}

     break;

   case 294: /* term: amper PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1754 "perly.y"
+#line 1746 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					scalar ((ps[-2].val.opval))
+					scalar ((ps[-2].val.opval)),
+					NULL
 				);
 			}

     break;

   case 295: /* term: amper PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE  */
-#line 1766 "perly.y"
+#line 1758 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						(ps[-1].val.opval),
-						scalar ((ps[-3].val.opval))
-					)
+					scalar ((ps[-3].val.opval)),
+					(ps[-1].val.opval)
 				);
 			}

     break;

   case 296: /* term: NOAMP subname optlistexpr  */
-#line 1781 "perly.y"
+#line 1769 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						(ps[0].val.opval),
-						scalar ((ps[-1].val.opval))
-					)
+					scalar ((ps[-1].val.opval)),
+					(ps[0].val.opval)
 				);
 			}

     break;

   case 297: /* term: term ARROW PERLY_DOLLAR PERLY_STAR  */
-#line 1793 "perly.y"
+#line 1777 "perly.y"
                         { (yyval.opval) = newSVREF((ps[-3].val.opval)); }

     break;

   case 298: /* term: term ARROW PERLY_SNAIL PERLY_STAR  */
-#line 1795 "perly.y"
+#line 1779 "perly.y"
                         { (yyval.opval) = newAVREF((ps[-3].val.opval)); }

     break;

   case 299: /* term: term ARROW PERLY_PERCENT_SIGN PERLY_STAR  */
-#line 1797 "perly.y"
+#line 1781 "perly.y"
                         { (yyval.opval) = newHVREF((ps[-3].val.opval)); }

     break;

   case 300: /* term: term ARROW PERLY_AMPERSAND PERLY_STAR  */
-#line 1799 "perly.y"
-                        { (yyval.opval) = newUNOP(OP_ENTERSUB, 0,
-				       scalar(newCVREF((ps[-1].val.ival),(ps[-3].val.opval)))); }
+#line 1786 "perly.y"
+                        {
+				(yyval.opval) = build_function_invocation (
+					0,
+					scalar (newCVREF ((ps[-1].val.ival), (ps[-3].val.opval))),
+					NULL
+				);
+			}

     break;

   case 301: /* term: term ARROW PERLY_STAR PERLY_STAR  */
-#line 1802 "perly.y"
+#line 1794 "perly.y"
                         { (yyval.opval) = newGVREF(0,(ps[-3].val.opval)); }

     break;

   case 302: /* term: LOOPEX  */
-#line 1804 "perly.y"
+#line 1796 "perly.y"
                         { (yyval.opval) = newOP((ps[0].val.ival), OPf_SPECIAL);
 			    PL_hints |= HINT_BLOCK_SCOPE; }

     break;

   case 303: /* term: LOOPEX term  */
-#line 1807 "perly.y"
+#line 1799 "perly.y"
                         { (yyval.opval) = newLOOPEX((ps[-1].val.ival),(ps[0].val.opval)); }

     break;

   case 304: /* term: NOTOP listexpr  */
-#line 1809 "perly.y"
+#line 1801 "perly.y"
                         { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); }

     break;

   case 305: /* term: UNIOP  */
-#line 1811 "perly.y"
+#line 1803 "perly.y"
                         { (yyval.opval) = newOP((ps[0].val.ival), 0); }

     break;

   case 306: /* term: UNIOP block  */
-#line 1813 "perly.y"
+#line 1805 "perly.y"
                         { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); }

     break;

   case 307: /* term: UNIOP term  */
-#line 1815 "perly.y"
+#line 1807 "perly.y"
                         { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); }

     break;

   case 308: /* term: KW_REQUIRE  */
-#line 1817 "perly.y"
+#line 1809 "perly.y"
                         { (yyval.opval) = newOP(OP_REQUIRE, (ps[0].val.ival) ? OPf_SPECIAL : 0); }

     break;

   case 309: /* term: KW_REQUIRE term  */
-#line 1819 "perly.y"
+#line 1811 "perly.y"
                         { (yyval.opval) = newUNOP(OP_REQUIRE, (ps[-1].val.ival) ? OPf_SPECIAL : 0, (ps[0].val.opval)); }

     break;

   case 310: /* term: UNIOPSUB  */
-#line 1821 "perly.y"
+#line 1813 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					scalar ((ps[0].val.opval))
+					scalar ((ps[0].val.opval)),
+					NULL
 				);
 			}

     break;

   case 311: /* term: UNIOPSUB term  */
-#line 1831 "perly.y"
+#line 1823 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						(ps[0].val.opval),
-						scalar ((ps[-1].val.opval))
-					)
+					scalar ((ps[-1].val.opval)),
+					(ps[0].val.opval)
 				);
 			}

     break;

   case 312: /* term: FUNC0  */
-#line 1843 "perly.y"
+#line 1831 "perly.y"
                         { (yyval.opval) = newOP((ps[0].val.ival), 0); }

     break;

   case 313: /* term: FUNC0 PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1845 "perly.y"
+#line 1833 "perly.y"
                         { (yyval.opval) = newOP((ps[-2].val.ival), 0);}

     break;

   case 314: /* term: FUNC0OP  */
-#line 1847 "perly.y"
+#line 1835 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 315: /* term: FUNC0OP PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1849 "perly.y"
+#line 1837 "perly.y"
                         { (yyval.opval) = (ps[-2].val.opval); }

     break;

   case 316: /* term: FUNC0SUB  */
-#line 1852 "perly.y"
+#line 1840 "perly.y"
                         {
-				(yyval.opval) = newUNOP (
-					OP_ENTERSUB,
+				(yyval.opval) = build_function_invocation (
 					OPf_STACKED,
-					scalar ((ps[0].val.opval))
+					scalar ((ps[0].val.opval)),
+					NULL
 				);
 			}

     break;

   case 317: /* term: FUNC1 PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1860 "perly.y"
+#line 1848 "perly.y"
                         { (yyval.opval) = ((ps[-2].val.ival) == OP_NOT)
                           ? newUNOP((ps[-2].val.ival), 0, newSVOP(OP_CONST, 0, newSViv(0)))
                           : newOP((ps[-2].val.ival), OPf_SPECIAL); }
@@ -2124,13 +2109,13 @@ case 2: /* @1: %empty  */
     break;

   case 318: /* term: FUNC1 PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE  */
-#line 1864 "perly.y"
+#line 1852 "perly.y"
                         { (yyval.opval) = newUNOP((ps[-3].val.ival), 0, (ps[-1].val.opval)); }

     break;

   case 319: /* @25: %empty  */
-#line 1866 "perly.y"
+#line 1854 "perly.y"
                         {
 			    if (   (ps[0].val.opval)->op_type != OP_TRANS
 			        && (ps[0].val.opval)->op_type != OP_TRANSR
@@ -2145,67 +2130,67 @@ case 2: /* @1: %empty  */
     break;

   case 320: /* term: PMFUNC @25 SUBLEXSTART listexpr optrepl SUBLEXEND  */
-#line 1877 "perly.y"
+#line 1865 "perly.y"
                         { (yyval.opval) = pmruntime((ps[-5].val.opval), (ps[-2].val.opval), (ps[-1].val.opval), 1, (ps[-4].val.ival)); }

     break;

   case 324: /* myattrterm: KW_MY myterm attrlist  */
-#line 1886 "perly.y"
+#line 1874 "perly.y"
                         { (yyval.opval) = my_attrs((ps[-1].val.opval),(ps[0].val.opval)); }

     break;

   case 325: /* myattrterm: KW_MY myterm  */
-#line 1888 "perly.y"
+#line 1876 "perly.y"
                         { (yyval.opval) = localize((ps[0].val.opval),1); }

     break;

   case 326: /* myattrterm: KW_MY REFGEN myterm attrlist  */
-#line 1890 "perly.y"
+#line 1878 "perly.y"
                         { (yyval.opval) = newUNOP(OP_REFGEN, 0, my_attrs((ps[-1].val.opval),(ps[0].val.opval))); }

     break;

   case 327: /* myattrterm: KW_MY REFGEN term  */
-#line 1892 "perly.y"
+#line 1880 "perly.y"
                         { (yyval.opval) = newUNOP(OP_REFGEN, 0, localize((ps[0].val.opval),1)); }

     break;

   case 328: /* myterm: PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE  */
-#line 1897 "perly.y"
+#line 1885 "perly.y"
                         { (yyval.opval) = sawparens((ps[-1].val.opval)); }

     break;

   case 329: /* myterm: PERLY_PAREN_OPEN PERLY_PAREN_CLOSE  */
-#line 1899 "perly.y"
+#line 1887 "perly.y"
                         { (yyval.opval) = sawparens(newNULLLIST()); }

     break;

   case 330: /* myterm: scalar  */
-#line 1902 "perly.y"
+#line 1890 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 331: /* myterm: hsh  */
-#line 1904 "perly.y"
+#line 1892 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 332: /* myterm: ary  */
-#line 1906 "perly.y"
+#line 1894 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 333: /* fieldvar: scalar  */
-#line 1911 "perly.y"
+#line 1899 "perly.y"
                         {
 			  (yyval.pval) = PadnamelistARRAY(PL_comppad_name)[(ps[0].val.opval)->op_targ];
 			  op_free((ps[0].val.opval));
@@ -2214,7 +2199,7 @@ case 2: /* @1: %empty  */
     break;

   case 334: /* fieldvar: hsh  */
-#line 1916 "perly.y"
+#line 1904 "perly.y"
                         {
 			  (yyval.pval) = PadnamelistARRAY(PL_comppad_name)[(ps[0].val.opval)->op_targ];
 			  op_free((ps[0].val.opval));
@@ -2223,7 +2208,7 @@ case 2: /* @1: %empty  */
     break;

   case 335: /* fieldvar: ary  */
-#line 1921 "perly.y"
+#line 1909 "perly.y"
                         {
 			  (yyval.pval) = PadnamelistARRAY(PL_comppad_name)[(ps[0].val.opval)->op_targ];
 			  op_free((ps[0].val.opval));
@@ -2232,7 +2217,7 @@ case 2: /* @1: %empty  */
     break;

   case 336: /* fielddecl: KW_FIELD fieldvar optattrlist  */
-#line 1929 "perly.y"
+#line 1917 "perly.y"
                         {
 			  parser->in_my = 0;
 			  if((ps[0].val.opval))
@@ -2243,7 +2228,7 @@ case 2: /* @1: %empty  */
     break;

   case 337: /* $@26: %empty  */
-#line 1936 "perly.y"
+#line 1924 "perly.y"
                         {
 			  parser->in_my = 0;
 			  if((ps[-1].val.opval))
@@ -2255,7 +2240,7 @@ case 2: /* @1: %empty  */
     break;

   case 338: /* fielddecl: KW_FIELD fieldvar optattrlist ASSIGNOP $@26 term  */
-#line 1944 "perly.y"
+#line 1932 "perly.y"
                         {
 			  class_set_field_defop((PADNAME *)(ps[-4].val.pval), (ps[-2].val.ival), (ps[0].val.opval));
 			  LEAVE;
@@ -2265,25 +2250,25 @@ case 2: /* @1: %empty  */
     break;

   case 344: /* optrepl: PERLY_SLASH expr  */
-#line 1964 "perly.y"
+#line 1952 "perly.y"
                                         { (yyval.opval) = (ps[0].val.opval); }

     break;

   case 345: /* my_scalar: scalar  */
-#line 1970 "perly.y"
+#line 1958 "perly.y"
                         { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); }

     break;

   case 346: /* list_of_itervars: list_of_itervars PERLY_COMMA  */
-#line 1975 "perly.y"
+#line 1963 "perly.y"
                         { (yyval.opval) = (ps[-1].val.opval); }

     break;

   case 347: /* list_of_itervars: list_of_itervars PERLY_COMMA scalar  */
-#line 1977 "perly.y"
+#line 1965 "perly.y"
                         {
 			  (yyval.opval) = op_append_elem(OP_LIST, (ps[-2].val.opval), (ps[0].val.opval));
 			}
@@ -2291,7 +2276,7 @@ case 2: /* @1: %empty  */
     break;

   case 348: /* list_of_itervars: list_of_itervars PERLY_COMMA REFGEN my_var  */
-#line 1981 "perly.y"
+#line 1969 "perly.y"
                         {
 			  (yyval.opval) = op_append_elem(OP_LIST, (ps[-3].val.opval), newUNOP(OP_REFGEN, 0, (ps[0].val.opval)));
 			}
@@ -2299,7 +2284,7 @@ case 2: /* @1: %empty  */
     break;

   case 350: /* list_of_itervars: REFGEN my_var  */
-#line 1986 "perly.y"
+#line 1974 "perly.y"
                         {
 			  (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval));
 			}
@@ -2307,25 +2292,25 @@ case 2: /* @1: %empty  */
     break;

   case 351: /* my_list_of_itervars: list_of_itervars  */
-#line 1992 "perly.y"
+#line 1980 "perly.y"
                         { parser->in_my = 0; (yyval.opval) = (ps[0].val.opval); }

     break;

   case 359: /* amper: PERLY_AMPERSAND indirob  */
-#line 2009 "perly.y"
+#line 1997 "perly.y"
                         { (yyval.opval) = newCVREF((ps[-1].val.ival),(ps[0].val.opval)); }

     break;

   case 360: /* scalar: PERLY_DOLLAR indirob  */
-#line 2013 "perly.y"
+#line 2001 "perly.y"
                         { (yyval.opval) = newSVREF((ps[0].val.opval)); }

     break;

   case 361: /* ary: PERLY_SNAIL indirob  */
-#line 2017 "perly.y"
+#line 2005 "perly.y"
                         { (yyval.opval) = newAVREF((ps[0].val.opval));
 			  if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival);
 			}
@@ -2333,7 +2318,7 @@ case 2: /* @1: %empty  */
     break;

   case 362: /* hsh: PERLY_PERCENT_SIGN indirob  */
-#line 2023 "perly.y"
+#line 2011 "perly.y"
                         { (yyval.opval) = newHVREF((ps[0].val.opval));
 			  if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival);
 			}
@@ -2341,61 +2326,61 @@ case 2: /* @1: %empty  */
     break;

   case 363: /* arylen: DOLSHARP indirob  */
-#line 2029 "perly.y"
+#line 2017 "perly.y"
                         { (yyval.opval) = newAVREF((ps[0].val.opval)); }

     break;

   case 364: /* arylen: term ARROW DOLSHARP PERLY_STAR  */
-#line 2031 "perly.y"
+#line 2019 "perly.y"
                         { (yyval.opval) = newAVREF((ps[-3].val.opval)); }

     break;

   case 365: /* star: PERLY_STAR indirob  */
-#line 2035 "perly.y"
+#line 2023 "perly.y"
                         { (yyval.opval) = newGVREF(0,(ps[0].val.opval)); }

     break;

   case 367: /* sliceme: term ARROW PERLY_SNAIL  */
-#line 2040 "perly.y"
+#line 2028 "perly.y"
                         { (yyval.opval) = newAVREF((ps[-2].val.opval)); }

     break;

   case 369: /* kvslice: term ARROW PERLY_PERCENT_SIGN  */
-#line 2045 "perly.y"
+#line 2033 "perly.y"
                         { (yyval.opval) = newHVREF((ps[-2].val.opval)); }

     break;

   case 371: /* gelem: term ARROW PERLY_STAR  */
-#line 2050 "perly.y"
+#line 2038 "perly.y"
                         { (yyval.opval) = newGVREF(0,(ps[-2].val.opval)); }

     break;

   case 372: /* indirob: BAREWORD  */
-#line 2055 "perly.y"
+#line 2043 "perly.y"
                         { (yyval.opval) = scalar((ps[0].val.opval)); }

     break;

   case 373: /* indirob: scalar  */
-#line 2057 "perly.y"
+#line 2045 "perly.y"
                         { (yyval.opval) = scalar((ps[0].val.opval)); }

     break;

   case 374: /* indirob: block  */
-#line 2059 "perly.y"
+#line 2047 "perly.y"
                         { (yyval.opval) = op_scope((ps[0].val.opval)); }

     break;

   case 375: /* indirob: PRIVATEREF  */
-#line 2062 "perly.y"
+#line 2050 "perly.y"
                         { (yyval.opval) = (ps[0].val.opval); }

     break;
@@ -2407,6 +2392,6 @@ case 2: /* @1: %empty  */


 /* Generated from:
- * 669a7ee3e72d22dac0af4ac0d27f8571b007da0f12042504c042d6c6db21a4e9 perly.y
+ * 929dc63ce54a4820bfd1a816b39ce87bc29a548457b00daf8373ae061bb933de perly.y
  * ba173fe7f0e9b6b5465fb5d0705af3290ac7d8b511f0eead585307eb6c68918d regen_perly.pl
  * ex: set ro ft=c: */
diff --git a/perly.h b/perly.h
index a2bf6b69d6..c00fcbf184 100644
--- a/perly.h
+++ b/perly.h
@@ -248,6 +248,6 @@ int yyparse (void);


 /* Generated from:
- * 669a7ee3e72d22dac0af4ac0d27f8571b007da0f12042504c042d6c6db21a4e9 perly.y
+ * 929dc63ce54a4820bfd1a816b39ce87bc29a548457b00daf8373ae061bb933de perly.y
  * ba173fe7f0e9b6b5465fb5d0705af3290ac7d8b511f0eead585307eb6c68918d regen_perly.pl
  * ex: set ro ft=c: */
diff --git a/perly.tab b/perly.tab
index 727847495b..9abe4bbcee 100644
--- a/perly.tab
+++ b/perly.tab
@@ -385,24 +385,24 @@ static const yytype_int16 yyrline[] =
     1219,  1223,  1227,  1227,  1260,  1261,  1267,  1266,  1283,  1284,
     1289,  1294,  1288,  1306,  1308,  1310,  1312,  1314,  1318,  1320,
     1325,  1329,  1333,  1337,  1342,  1356,  1367,  1382,  1394,  1405,
-    1417,  1419,  1421,  1427,  1424,  1454,  1455,  1459,  1463,  1466,
-    1471,  1474,  1479,  1496,  1509,  1511,  1513,  1518,  1520,  1522,
-    1524,  1526,  1528,  1533,  1535,  1537,  1539,  1541,  1543,  1545,
-    1547,  1549,  1551,  1553,  1555,  1557,  1559,  1561,  1563,  1567,
-    1569,  1571,  1573,  1575,  1579,  1581,  1585,  1587,  1589,  1591,
-    1595,  1597,  1602,  1604,  1607,  1609,  1611,  1614,  1617,  1628,
-    1631,  1639,  1641,  1643,  1646,  1648,  1651,  1653,  1658,  1663,
-    1665,  1669,  1670,  1671,  1672,  1673,  1675,  1677,  1679,  1681,
-    1683,  1685,  1687,  1689,  1691,  1693,  1695,  1697,  1699,  1709,
-    1719,  1729,  1739,  1742,  1751,  1762,  1778,  1792,  1794,  1796,
-    1798,  1801,  1803,  1806,  1808,  1810,  1812,  1814,  1816,  1818,
-    1820,  1829,  1842,  1844,  1846,  1848,  1851,  1859,  1863,  1866,
-    1865,  1878,  1879,  1880,  1885,  1887,  1889,  1891,  1896,  1898,
-    1901,  1903,  1905,  1910,  1915,  1920,  1928,  1936,  1935,  1953,
-    1954,  1958,  1959,  1963,  1964,  1969,  1974,  1976,  1980,  1984,
-    1985,  1991,  1995,  1996,  1997,  2000,  2001,  2004,  2005,  2008,
-    2012,  2016,  2022,  2028,  2030,  2034,  2038,  2039,  2043,  2044,
-    2048,  2049,  2054,  2056,  2058,  2061
+    1417,  1419,  1421,  1427,  1424,  1450,  1451,  1455,  1459,  1462,
+    1467,  1470,  1475,  1488,  1501,  1503,  1505,  1510,  1512,  1514,
+    1516,  1518,  1520,  1525,  1527,  1529,  1531,  1533,  1535,  1537,
+    1539,  1541,  1543,  1545,  1547,  1549,  1551,  1553,  1555,  1559,
+    1561,  1563,  1565,  1567,  1571,  1573,  1577,  1579,  1581,  1583,
+    1587,  1589,  1594,  1596,  1599,  1601,  1603,  1606,  1609,  1620,
+    1623,  1631,  1633,  1635,  1638,  1640,  1643,  1645,  1650,  1655,
+    1657,  1661,  1662,  1663,  1664,  1665,  1667,  1669,  1671,  1673,
+    1675,  1677,  1679,  1681,  1683,  1685,  1687,  1689,  1691,  1701,
+    1711,  1721,  1731,  1734,  1743,  1754,  1766,  1776,  1778,  1780,
+    1782,  1793,  1795,  1798,  1800,  1802,  1804,  1806,  1808,  1810,
+    1812,  1821,  1830,  1832,  1834,  1836,  1839,  1847,  1851,  1854,
+    1853,  1866,  1867,  1868,  1873,  1875,  1877,  1879,  1884,  1886,
+    1889,  1891,  1893,  1898,  1903,  1908,  1916,  1924,  1923,  1941,
+    1942,  1946,  1947,  1951,  1952,  1957,  1962,  1964,  1968,  1972,
+    1973,  1979,  1983,  1984,  1985,  1988,  1989,  1992,  1993,  1996,
+    2000,  2004,  2010,  2016,  2018,  2022,  2026,  2027,  2031,  2032,
+    2036,  2037,  2042,  2044,  2046,  2049
 };
 #endif

@@ -1667,6 +1667,6 @@ static const toketypes yy_type_tab[] =
 };

 /* Generated from:
- * 669a7ee3e72d22dac0af4ac0d27f8571b007da0f12042504c042d6c6db21a4e9 perly.y
+ * 929dc63ce54a4820bfd1a816b39ce87bc29a548457b00daf8373ae061bb933de perly.y
  * ba173fe7f0e9b6b5465fb5d0705af3290ac7d8b511f0eead585307eb6c68918d regen_perly.pl
  * ex: set ro ft=c: */
diff --git a/perly.y b/perly.y
index d9d7841f5c..10f15dbd5d 100644
--- a/perly.y
+++ b/perly.y
@@ -1434,17 +1434,13 @@ listop	:	LSTOP indirob listexpr /* map {...} @args or print $fh @args */
 		%prec LSTOP
 		/* ... @bar */
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
+					$function,
+					op_prepend_elem (
 						OP_LIST,
-						op_prepend_elem (
-							OP_LIST,
-							$<opval>anonattrsub,
-							$optlistexpr
-						),
-						$function
+						$<opval>anonattrsub,
+						$optlistexpr
 					)
 				);
 			}
@@ -1478,30 +1474,26 @@ subscripted:    gelem subscript_keys[selector]        /* *main::{something} */
 	|	/* $subref->(@args); $foo->{bar}(@args) */
 		subscriptable_reference [code_reference]
 		PERLY_PAREN_OPEN
-		expr
+		expr                    [arguments]
 		PERLY_PAREN_CLOSE
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						$expr,
-						newCVREF (0, scalar ($code_reference))
-					)
+					newCVREF (0, scalar ($code_reference)),
+					$arguments
 				);
 				if (parser->expect == XBLOCK)
 					parser->expect = XOPERATOR;
 			}
-	|	subscriptable_reference[code_reference]
+	|	subscriptable_reference [code_reference]
 		PERLY_PAREN_OPEN
 		PERLY_PAREN_CLOSE
 		/* $subref->(); $foo->{bar}() */
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					newCVREF (0, scalar($code_reference))
+					newCVREF (0, scalar ($code_reference)),
+					NULL
 				);
 				if (parser->expect == XBLOCK)
 					parser->expect = XOPERATOR;
@@ -1741,10 +1733,10 @@ term[product]	:	termbinop
 	|	/* &foo; */
 		amper                       [function]
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					0,
-					scalar ($function)
+					scalar ($function),
+					NULL
 				);
 			}
 	|	/* &foo() or foo() */
@@ -1752,10 +1744,10 @@ term[product]	:	termbinop
 		PERLY_PAREN_OPEN
 		PERLY_PAREN_CLOSE
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					scalar ($function)
+					scalar ($function),
+					NULL
 				);
 			}
 	|	/* &foo(@args) or foo(@args) */
@@ -1764,14 +1756,10 @@ term[product]	:	termbinop
 		expr                        [arguments]
 		PERLY_PAREN_CLOSE
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						$arguments,
-						scalar ($function)
-					)
+					scalar ($function),
+					$arguments
 				);
 			}
 	|	/* foo @args (no parens) */
@@ -1779,14 +1767,10 @@ term[product]	:	termbinop
 		subname                     [function]
 		optlistexpr                 [arguments]
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						$arguments,
-						scalar ($function)
-					)
+					scalar ($function),
+					$arguments
 				);
 			}
 	|	term[operand] ARROW PERLY_DOLLAR PERLY_STAR
@@ -1795,9 +1779,17 @@ term[product]	:	termbinop
 			{ $$ = newAVREF($operand); }
 	|	term[operand] ARROW PERLY_PERCENT_SIGN PERLY_STAR
 			{ $$ = newHVREF($operand); }
-	|	term[operand] ARROW PERLY_AMPERSAND PERLY_STAR
-			{ $$ = newUNOP(OP_ENTERSUB, 0,
-				       scalar(newCVREF($PERLY_AMPERSAND,$operand))); }
+	|	term                        [code_reference]
+		ARROW
+		PERLY_AMPERSAND
+		PERLY_STAR
+			{
+				$$ = build_function_invocation (
+					0,
+					scalar (newCVREF ($PERLY_AMPERSAND, $code_reference)),
+					NULL
+				);
+			}
 	|	term[operand] ARROW PERLY_STAR PERLY_STAR	%prec PERLY_PAREN_OPEN
 			{ $$ = newGVREF(0,$operand); }
 	|	LOOPEX  /* loop exiting command (goto, last, dump, etc) */
@@ -1819,24 +1811,20 @@ term[product]	:	termbinop
 			{ $$ = newUNOP(OP_REQUIRE, $KW_REQUIRE ? OPf_SPECIAL : 0, $operand); }
 	|	UNIOPSUB                    [function]
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					scalar ($function)
+					scalar ($function),
+					NULL
 				);
 			}
 	|	/* Sub treated as unop */
 		UNIOPSUB                    [function]
 		term                        [arguments]
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					op_append_elem (
-						OP_LIST,
-						$arguments,
-						scalar ($function)
-					)
+					scalar ($function),
+					$arguments
 				);
 			}
 	|	FUNC0                                /* Nullary operator */
@@ -1850,10 +1838,10 @@ term[product]	:	termbinop
 	|	/* Sub treated as nullop */
 		FUNC0SUB                    [function]
 			{
-				$$ = newUNOP (
-					OP_ENTERSUB,
+				$$ = build_function_invocation (
 					OPf_STACKED,
-					scalar ($function)
+					scalar ($function),
+					NULL
 				);
 			}
 	|	FUNC1 PERLY_PAREN_OPEN PERLY_PAREN_CLOSE                        /* not () */
diff --git a/proto.h b/proto.h
index d57d113b28..0382e5934a 100644
--- a/proto.h
+++ b/proto.h
@@ -559,6 +559,16 @@ Perl_boot_core_mro(pTHX)
     STMT_START { Perl_assert_aTHX; PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT;  \
     } STMT_END

+PERL_CALLCONV OP *
+Perl_build_function_invocation(pTHX_ I32 flags, OP *code, OP *arguments)
+        Perl_attribute_nonnull_aTHX
+        Perl_attribute_nonnull(pTHX_2)
+        __attribute__visibility__("hidden");
+#define PERL_ARGS_ASSERT_BUILD_FUNCTION_INVOCATION \
+    STMT_START { Perl_assert_aTHX; assert(code);       \
+                 PERL_UNUSED_CONTEXT_FOR_ARGS_ASSERT;  \
+    } STMT_END
+
 PERL_CALLCONV OP *
 Perl_build_infix_plugin(pTHX_ OP *lhs, OP *rhs, void *tokendata)
         Perl_attribute_nonnull_aTHX