summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-09-06 00:51:16 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-09-06 06:18:08 -0700
commit199f858d54d30a550be7320e065420353bca5318 (patch)
treed59886518fdbd5c6bb873ebe8e54526cb45f521f
parentdd2a7f9048da2c440a4dfed5122c0bfd98f079d3 (diff)
downloadperl-199f858d54d30a550be7320e065420353bca5318.tar.gz
Put AV defelem creation code in one place
-rw-r--r--embed.fnc1
-rw-r--r--embed.h1
-rw-r--r--pp_ctl.c10
-rw-r--r--pp_hot.c29
-rw-r--r--proto.h7
-rw-r--r--sv.c13
6 files changed, 29 insertions, 32 deletions
diff --git a/embed.fnc b/embed.fnc
index 088086e294..11425ad8a7 100644
--- 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 7708a61ff7..3662b97d3a 100644
--- a/embed.h
+++ b/embed.h
@@ -1186,6 +1186,7 @@
#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)
diff --git a/pp_ctl.c b/pp_ctl.c
index b7b3598b7c..d091e29f0e 100644
--- 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);
diff --git a/pp_hot.c b/pp_hot.c
index 3b96643b00..2598ef0f58 100644
--- 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 a3106cbfac..7819f21fb0 100644
--- 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 f53ffdde2a..d6f3338b08 100644
--- 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