@@ -7700,6 +7700,23 @@ PP(pp_anonconst)
7700
7700
}
7701
7701
7702
7702
7703
+ /* Helper function for use during signature argument handling from @_.
7704
+ * Replaces elements in an AV with a new SV cloned from the original value
7705
+ * at each position from startix onwards until endix.
7706
+ */
7707
+ #define av_refresh_elements_range (av , startix , endix ) S_av_refresh_elements_range(aTHX_ av, startix, endix)
7708
+ STATIC void
7709
+ S_av_refresh_elements_range (pTHX_ AV * av , IV startix , IV endix )
7710
+ {
7711
+ for (IV ix = startix ; ix < endix ; ix ++ ) {
7712
+ SV * * svp = av_fetch (av , ix , FALSE);
7713
+ SV * newsv = newSVsv_flags (svp ? * svp : & PL_sv_undef ,
7714
+ (SV_DO_COW_SVSETSV |SV_NOSTEAL ));
7715
+ if (!av_store (av , ix , newsv ))
7716
+ SvREFCNT_dec_NN (newsv );
7717
+ }
7718
+ }
7719
+
7703
7720
/* process one subroutine argument - typically when the sub has a signature:
7704
7721
* introduce PL_curpad[op_targ] and assign to it the value
7705
7722
* for $: (OPf_STACKED ? *sp : $_[N])
@@ -7778,13 +7795,7 @@ PP_wrapped(pp_argelem,
7778
7795
* to avoid the equivalent of @a = ($a[0]) prematurely freeing
7779
7796
* elements. See similar code in pp_aassign.
7780
7797
*/
7781
- for (i = 0 ; i < argc ; i ++ ) {
7782
- SV * * svp = av_fetch (defav , ix + i , FALSE);
7783
- SV * newsv = newSVsv_flags (svp ? * svp : & PL_sv_undef ,
7784
- (SV_DO_COW_SVSETSV |SV_NOSTEAL ));
7785
- if (!av_store (defav , ix + i , newsv ))
7786
- SvREFCNT_dec_NN (newsv );
7787
- }
7798
+ av_refresh_elements_range (defav , ix , ix + argc );
7788
7799
av_clear ((AV * )targ );
7789
7800
}
7790
7801
@@ -7810,13 +7821,7 @@ PP_wrapped(pp_argelem,
7810
7821
7811
7822
if (SvRMAGICAL (targ ) || HvUSEDKEYS ((HV * )targ )) {
7812
7823
/* see "target should usually be empty" comment above */
7813
- for (i = 0 ; i < argc ; i ++ ) {
7814
- SV * * svp = av_fetch (defav , ix + i , FALSE);
7815
- SV * newsv = newSVsv_flags (svp ? * svp : & PL_sv_undef ,
7816
- (SV_DO_COW_SVSETSV |SV_NOSTEAL ));
7817
- if (!av_store (defav , ix + i , newsv ))
7818
- SvREFCNT_dec_NN (newsv );
7819
- }
7824
+ av_refresh_elements_range (defav , ix , ix + argc );
7820
7825
hv_clear ((HV * )targ );
7821
7826
}
7822
7827
@@ -7907,20 +7912,10 @@ S_find_runcv_name(void)
7907
7912
* signatured subs.
7908
7913
*/
7909
7914
7910
- PP (pp_argcheck )
7915
+ static void
7916
+ S_check_argc (pTHX_ UV argc , UV params , UV opt_params , char slurpy )
7911
7917
{
7912
- OP * const o = PL_op ;
7913
- struct op_argcheck_aux * aux = (struct op_argcheck_aux * )cUNOP_AUXo -> op_aux ;
7914
- UV params = aux -> params ;
7915
- UV opt_params = aux -> opt_params ;
7916
- char slurpy = aux -> slurpy ;
7917
- AV * defav = GvAV (PL_defgv ); /* @_ */
7918
- UV argc ;
7919
- bool too_few ;
7920
-
7921
- assert (!SvMAGICAL (defav ));
7922
- argc = (UV )(AvFILLp (defav ) + 1 );
7923
- too_few = (argc < (params - opt_params ));
7918
+ bool too_few = (argc < (params - opt_params ));
7924
7919
7925
7920
if (UNLIKELY (too_few || (!slurpy && argc > params )))
7926
7921
@@ -7939,6 +7934,18 @@ PP(pp_argcheck)
7939
7934
/* diag_listed_as: Odd name/value argument for subroutine '%s' */
7940
7935
Perl_croak_caller ("Odd name/value argument for subroutine '%" SVf "'" ,
7941
7936
S_find_runcv_name ());
7937
+ }
7938
+
7939
+ PP (pp_argcheck )
7940
+ {
7941
+ OP * const o = PL_op ;
7942
+ struct op_argcheck_aux * aux = (struct op_argcheck_aux * )cUNOP_AUXo -> op_aux ;
7943
+ AV * defav = GvAV (PL_defgv ); /* @_ */
7944
+
7945
+ assert (!SvMAGICAL (defav ));
7946
+ UV argc = (UV )(AvFILLp (defav ) + 1 );
7947
+
7948
+ S_check_argc (aTHX_ argc , aux -> params , aux -> opt_params , aux -> slurpy );
7942
7949
7943
7950
return NORMAL ;
7944
7951
}
0 commit comments