summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-01-06 13:50:35 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-01-06 13:50:35 -0800
commit9f71cfe6ef2a57e26394d4caf1bf2894802f4777 (patch)
tree55b4e2aa0dc91477963674d95f1aa6f9ab1f5236 /pp_hot.c
parentbd4675851936488a7b28a813c5b60248be3e733b (diff)
downloadperl-9f71cfe6ef2a57e26394d4caf1bf2894802f4777.tar.gz
[perl #107440] Save av/hv on mortals stack when clearing
In pp_undef and pp_aassign, we should put the av or hv that is being cleared on the mortals stack (with an increased refcount), so that destructors fired during the clearing do not free the av or hv. I was going to put this in av_undef, etc., but pp_aassign also needs to access the aggregate after clearing it. We still get a crash with that approach. Putting the aggregate on the mortals stack in av_undef, av_clear and h_freeentries would work, too, but might cause the aggregate to leak too far. That may cause problems, e.g., if it is %^H, because it may last until the end of the current compilation unit. Directly inside a runloop (in a pp function), it should be OK to use the mortals stack, as it *will* be cleared ‘soon’. This seems the least intrusive approach.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/pp_hot.c b/pp_hot.c
index ec7674ea85..add940049b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -993,7 +993,7 @@ PP(pp_aassign)
sv = *lelem++;
switch (SvTYPE(sv)) {
case SVt_PVAV:
- ary = MUTABLE_AV(sv);
+ ary = MUTABLE_AV(sv_2mortal(SvREFCNT_inc_simple_NN(sv)));
magic = SvMAGICAL(ary) != 0;
av_clear(ary);
av_extend(ary, lastrelem - relem);
@@ -1020,7 +1020,7 @@ PP(pp_aassign)
SV *tmpstr;
SV** topelem = relem;
- hash = MUTABLE_HV(sv);
+ hash = MUTABLE_HV(sv_2mortal(SvREFCNT_inc_simple_NN(sv)));
magic = SvMAGICAL(hash) != 0;
hv_clear(hash);
firsthashrelem = relem;