This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Put AV defelem creation code in one place
authorFather Chrysostomos <sprout@cpan.org>
Fri, 6 Sep 2013 07:51:16 +0000 (00:51 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 6 Sep 2013 13:18:08 +0000 (06:18 -0700)
embed.fnc
embed.h
pp_ctl.c
pp_hot.c
proto.h
sv.c

index 088086e..11425ad 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -966,6 +966,7 @@ Apda        |SV*    |newRV_noinc    |NN SV *const sv
 Apda   |SV*    |newSV          |const STRLEN len
 Apa    |OP*    |newSVREF       |NN OP* o
 Apda   |OP*    |newSVOP        |I32 type|I32 flags|NN SV* sv
+pa     |SV*    |newSVavdefelem |NN AV *av|SSize_t ix|bool extendible
 Apda   |SV*    |newSViv        |const IV i
 Apda   |SV*    |newSVuv        |const UV u
 Apda   |SV*    |newSVnv        |const NV n
diff --git a/embed.h b/embed.h
index 7708a61..3662b97 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define my_unexec()            Perl_my_unexec(aTHX)
 #define newATTRSUB_flags(a,b,c,d,e,f)  Perl_newATTRSUB_flags(aTHX_ a,b,c,d,e,f)
 #define newSTUB(a,b)           Perl_newSTUB(aTHX_ a,b)
+#define newSVavdefelem(a,b,c)  Perl_newSVavdefelem(aTHX_ a,b,c)
 #define newXS_len_flags(a,b,c,d,e,f,g) Perl_newXS_len_flags(aTHX_ a,b,c,d,e,f,g)
 #define nextargv(a)            Perl_nextargv(aTHX_ a)
 #define oopsAV(a)              Perl_oopsAV(aTHX_ a)
index b7b3598..d091e29 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2910,14 +2910,8 @@ PP(pp_goto)
                        if (SP[-index])
                            SvREFCNT_inc_void_NN(sv_2mortal(SP[-index]));
                        else {
-                           SV * const lv =
-                               sv_2mortal(newSV_type(SVt_PVLV));
-                           SP[-index] = lv;
-                           LvTYPE(lv) = 'y';
-                           sv_magic(lv,NULL,PERL_MAGIC_defelem,NULL,0);
-                           LvTARG(lv) = SvREFCNT_inc_simple_NN(arg);
-                           LvSTARGOFF(lv) = AvFILLp(arg) - index;
-                           LvTARGLEN(lv) = 1;
+                           SP[-index] = sv_2mortal(newSVavdefelem(arg,
+                                                AvFILLp(arg) - index, 1));
                        }
                }
                SvREFCNT_dec(arg);
index 3b96643..2598ef0 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1919,13 +1919,7 @@ PP(pp_iter)
             }
         }
         else if (!av_is_stack) {
-            SV *lv = newSV_type(SVt_PVLV);
-            LvTYPE(lv) = 'y';
-            sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
-            LvTARG(lv) = SvREFCNT_inc_simple(av);
-            LvTARGOFF(lv) = ix;
-            LvTARGLEN(lv) = (STRLEN)UV_MAX;
-            sv = lv;
+            sv = newSVavdefelem(av, ix, 0);
         }
         else
             sv = &PL_sv_undef;
@@ -2734,13 +2728,7 @@ try_autoload:
                for (; i < items; ++i)
                    if (AvARRAY(av)[i]) SP[i+1] = AvARRAY(av)[i];
                    else {
-                       SV * const lv = sv_2mortal(newSV_type(SVt_PVLV));
-                       SP[i+1] = lv;
-                       LvTYPE(lv) = 'y';
-                       sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
-                       LvTARG(lv) = SvREFCNT_inc_simple_NN(av);
-                       LvSTARGOFF(lv) = i;
-                       LvTARGLEN(lv) = 1;
+                       SP[i+1] = newSVavdefelem(av, i, 1);
                    }
                SP += items;
                PUTBACK ;               
@@ -2850,23 +2838,16 @@ PP(pp_aelem)
         }
 #endif
        if (!svp || !*svp) {
-           SV* lv;
            IV len;
            if (!defer)
                DIE(aTHX_ PL_no_aelem, elem);
            len = av_len(av);
-           lv = sv_newmortal();
-           sv_upgrade(lv, SVt_PVLV);
-           LvTYPE(lv) = 'y';
-           sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
-           LvTARG(lv) = SvREFCNT_inc_simple_NN(av);
+           mPUSHs(newSVavdefelem(av,
            /* Resolve a negative index now, unless it points before the
               beginning of the array, in which case record it for error
               reporting in magic_setdefelem. */
-           LvSTARGOFF(lv) =
-               elem < 0 && len + elem >= 0 ? len + elem : elem;
-           LvTARGLEN(lv) = 1;
-           PUSHs(lv);
+               elem < 0 && len + elem >= 0 ? len + elem : elem,
+               1));
            RETURN;
        }
        if (localizing) {
diff --git a/proto.h b/proto.h
index a3106cb..7819f21 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -2888,6 +2888,13 @@ PERL_CALLCONV SV*        Perl_newSV_type(pTHX_ const svtype type)
                        __attribute__malloc__
                        __attribute__warn_unused_result__;
 
+PERL_CALLCONV SV*      Perl_newSVavdefelem(pTHX_ AV *av, SSize_t ix, bool extendible)
+                       __attribute__malloc__
+                       __attribute__warn_unused_result__
+                       __attribute__nonnull__(pTHX_1);
+#define PERL_ARGS_ASSERT_NEWSVAVDEFELEM        \
+       assert(av)
+
 PERL_CALLCONV SV*      Perl_newSVhek(pTHX_ const HEK *const hek)
                        __attribute__malloc__
                        __attribute__warn_unused_result__;
diff --git a/sv.c b/sv.c
index f53ffdd..d6f3338 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9661,6 +9661,19 @@ Perl_newSVrv(pTHX_ SV *const rv, const char *const classname)
     return sv;
 }
 
+SV *
+Perl_newSVavdefelem(pTHX_ AV *av, SSize_t ix, bool extendible)
+{
+    SV * const lv = newSV_type(SVt_PVLV);
+    PERL_ARGS_ASSERT_NEWSVAVDEFELEM;
+    LvTYPE(lv) = 'y';
+    sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
+    LvTARG(lv) = SvREFCNT_inc_simple_NN(av);
+    LvSTARGOFF(lv) = ix;
+    LvTARGLEN(lv) = extendible ? 1 : (STRLEN)UV_MAX;
+    return lv;
+}
+
 /*
 =for apidoc sv_setref_pv