diff options
author | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2023-02-12 18:15:46 +0000 |
---|---|---|
committer | Paul Evans <leonerd@leonerd.org.uk> | 2023-02-13 17:41:49 +0000 |
commit | 857b55419b96b59cb074d897ac8e6154bbe1e1d2 (patch) | |
tree | 61d4870762090a21c87eb5630e2e3608c75103a7 | |
parent | e7faea54386fae0e542ca8bfe43a8c5444c69114 (diff) | |
download | perl-857b55419b96b59cb074d897ac8e6154bbe1e1d2.tar.gz |
Refactor out the part of sv_dup that clones the HvAUX structure into its own helper function
-rw-r--r-- | embed.fnc | 3 | ||||
-rw-r--r-- | embed.h | 1 | ||||
-rw-r--r-- | proto.h | 5 | ||||
-rw-r--r-- | sv.c | 132 |
4 files changed, 77 insertions, 64 deletions
@@ -5656,6 +5656,9 @@ S |SV ** |sv_dup_inc_multiple \ |NN SV **dest \ |SSize_t items \ |NN CLONE_PARAMS * const param +S |void |sv_dup_hvaux |NN const SV * const ssv \ + |NN SV *dsv \ + |NN CLONE_PARAMS * const param SR |SV * |sv_dup_common |NN const SV * const ssv \ |NN CLONE_PARAMS * const param S |void |unreferenced_to_tmp_stack \ @@ -2055,6 +2055,7 @@ # endif /* defined(PERL_DEBUG_READONLY_COW) */ # if defined(USE_ITHREADS) # define sv_dup_common(a,b) S_sv_dup_common(aTHX_ a,b) +# define sv_dup_hvaux(a,b,c) S_sv_dup_hvaux(aTHX_ a,b,c) # define sv_dup_inc_multiple(a,b,c,d) S_sv_dup_inc_multiple(aTHX_ a,b,c,d) # define unreferenced_to_tmp_stack(a) S_unreferenced_to_tmp_stack(aTHX_ a) # endif /* defined(USE_ITHREADS) */ @@ -9195,6 +9195,11 @@ S_sv_dup_common(pTHX_ const SV * const ssv, CLONE_PARAMS * const param) # define PERL_ARGS_ASSERT_SV_DUP_COMMON \ assert(ssv); assert(param) +STATIC void +S_sv_dup_hvaux(pTHX_ const SV * const ssv, SV *dsv, CLONE_PARAMS * const param); +# define PERL_ARGS_ASSERT_SV_DUP_HVAUX \ + assert(ssv); assert(dsv); assert(param) + STATIC SV ** S_sv_dup_inc_multiple(pTHX_ SV * const *source, SV **dest, SSize_t items, CLONE_PARAMS * const param); # define PERL_ARGS_ASSERT_SV_DUP_INC_MULTIPLE \ @@ -14423,6 +14423,72 @@ S_sv_dup_inc_multiple(pTHX_ SV *const *source, SV **dest, return dest; } +/* duplicate the HvAUX of an HV */ +static void +S_sv_dup_hvaux(pTHX_ const SV *const ssv, SV *dsv, CLONE_PARAMS *const param) +{ + PERL_ARGS_ASSERT_SV_DUP_HVAUX; + + const struct xpvhv_aux * const saux = HvAUX(ssv); + struct xpvhv_aux * const daux = HvAUX(dsv); + /* This flag isn't copied. */ + SvOOK_on(dsv); + + if (saux->xhv_name_count) { + HEK ** const sname = saux->xhv_name_u.xhvnameu_names; + const I32 count = saux->xhv_name_count < 0 + ? -saux->xhv_name_count + : saux->xhv_name_count; + HEK **shekp = sname + count; + HEK **dhekp; + Newx(daux->xhv_name_u.xhvnameu_names, count, HEK *); + dhekp = daux->xhv_name_u.xhvnameu_names + count; + while (shekp-- > sname) { + dhekp--; + *dhekp = hek_dup(*shekp, param); + } + } + else { + daux->xhv_name_u.xhvnameu_name = hek_dup(saux->xhv_name_u.xhvnameu_name, param); + } + daux->xhv_name_count = saux->xhv_name_count; + + daux->xhv_aux_flags = saux->xhv_aux_flags; +#ifdef PERL_HASH_RANDOMIZE_KEYS + daux->xhv_rand = saux->xhv_rand; + daux->xhv_last_rand = saux->xhv_last_rand; +#endif + daux->xhv_riter = saux->xhv_riter; + daux->xhv_eiter = saux->xhv_eiter ? he_dup(saux->xhv_eiter, FALSE, param) : 0; + /* backref array needs refcnt=2; see sv_add_backref */ + daux->xhv_backreferences = + (param->flags & CLONEf_JOIN_IN) + /* when joining, we let the individual GVs and + * CVs add themselves to backref as + * needed. This avoids pulling in stuff + * that isn't required, and simplifies the + * case where stashes aren't cloned back + * if they already exist in the parent + * thread */ + ? NULL + : saux->xhv_backreferences + ? (SvTYPE(saux->xhv_backreferences) == SVt_PVAV) + ? MUTABLE_AV(SvREFCNT_inc( + sv_dup_inc((const SV *) + saux->xhv_backreferences, param))) + : MUTABLE_AV(sv_dup((const SV *) + saux->xhv_backreferences, param)) + : 0; + + daux->xhv_mro_meta = saux->xhv_mro_meta + ? mro_meta_dup(saux->xhv_mro_meta, param) + : 0; + + /* Record stashes for possible cloning in Perl_clone(). */ + if (HvNAME(ssv)) + av_push(param->stashes, dsv); +} + /* duplicate an SV of any type (including AV, HV etc) */ static SV * @@ -14731,70 +14797,8 @@ S_sv_dup_common(pTHX_ const SV *const ssv, CLONE_PARAMS *const param) ? he_dup(source, FALSE, param) : 0; ++i; } - if (HvHasAUX(ssv)) { - const struct xpvhv_aux * const saux = HvAUX(ssv); - struct xpvhv_aux * const daux = HvAUX(dsv); - /* This flag isn't copied. */ - SvOOK_on(dsv); - - if (saux->xhv_name_count) { - HEK ** const sname = saux->xhv_name_u.xhvnameu_names; - const I32 count - = saux->xhv_name_count < 0 - ? -saux->xhv_name_count - : saux->xhv_name_count; - HEK **shekp = sname + count; - HEK **dhekp; - Newx(daux->xhv_name_u.xhvnameu_names, count, HEK *); - dhekp = daux->xhv_name_u.xhvnameu_names + count; - while (shekp-- > sname) { - dhekp--; - *dhekp = hek_dup(*shekp, param); - } - } - else { - daux->xhv_name_u.xhvnameu_name - = hek_dup(saux->xhv_name_u.xhvnameu_name, - param); - } - daux->xhv_name_count = saux->xhv_name_count; - - daux->xhv_aux_flags = saux->xhv_aux_flags; -#ifdef PERL_HASH_RANDOMIZE_KEYS - daux->xhv_rand = saux->xhv_rand; - daux->xhv_last_rand = saux->xhv_last_rand; -#endif - daux->xhv_riter = saux->xhv_riter; - daux->xhv_eiter = saux->xhv_eiter - ? he_dup(saux->xhv_eiter, FALSE, param) : 0; - /* backref array needs refcnt=2; see sv_add_backref */ - daux->xhv_backreferences = - (param->flags & CLONEf_JOIN_IN) - /* when joining, we let the individual GVs and - * CVs add themselves to backref as - * needed. This avoids pulling in stuff - * that isn't required, and simplifies the - * case where stashes aren't cloned back - * if they already exist in the parent - * thread */ - ? NULL - : saux->xhv_backreferences - ? (SvTYPE(saux->xhv_backreferences) == SVt_PVAV) - ? MUTABLE_AV(SvREFCNT_inc( - sv_dup_inc((const SV *) - saux->xhv_backreferences, param))) - : MUTABLE_AV(sv_dup((const SV *) - saux->xhv_backreferences, param)) - : 0; - - daux->xhv_mro_meta = saux->xhv_mro_meta - ? mro_meta_dup(saux->xhv_mro_meta, param) - : 0; - - /* Record stashes for possible cloning in Perl_clone(). */ - if (HvNAME(ssv)) - av_push(param->stashes, dsv); - } + if (HvHasAUX(ssv)) + sv_dup_hvaux(ssv, dsv, param); } else HvARRAY(MUTABLE_HV(dsv)) = NULL; |