diff options
-rw-r--r-- | pod/perldelta.pod | 4 | ||||
-rw-r--r-- | pp.c | 7 | ||||
-rw-r--r-- | t/op/reverse.t | 16 |
3 files changed, 25 insertions, 2 deletions
diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 46f5e57092..1ea6c597ec 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -387,7 +387,9 @@ files in F<ext/> and F<lib/> are best summarized in L</Modules and Pragmata>. =item * -XXX +The in-place reverse optimisation now correctly strengthens weak +references using the L<C<sv_rvunweaken()>|perlapi/sv_rvunweaken> +API function. =back @@ -5586,7 +5586,14 @@ PP(pp_reverse) SV * const tmp = *begin; *begin++ = *end; *end-- = tmp; + + if (tmp && SvWEAKREF(tmp)) + sv_rvunweaken(tmp); } + + /* make sure we catch the middle element */ + if (begin == end && *begin && SvWEAKREF(*begin)) + sv_rvunweaken(*begin); } } } diff --git a/t/op/reverse.t b/t/op/reverse.t index 74e6295446..fd06560fdf 100644 --- a/t/op/reverse.t +++ b/t/op/reverse.t @@ -6,7 +6,7 @@ BEGIN { set_up_inc('../lib'); } -plan tests => 23; +plan tests => 25; is(reverse("abc"), "cba", 'simple reverse'); @@ -91,3 +91,17 @@ use Tie::Array; my $c = scalar reverse($b); is($a, $c, 'Unicode string double reversal matches original'); } + +# in-place reversing of weak references +SKIP: { + skip_if_miniperl("no dynamic loading on miniperl, no extension Scalar::Util", 2); + require Scalar::Util; + my @a = map { \(my $dummy = $_) } 1..5; # odd number of elements + my @r = @a[0,2]; # middle and non-middle element + Scalar::Util::weaken($a[0]); + Scalar::Util::weaken($a[2]); + @a = reverse @a; + @r = (); + ok defined $a[-1] && ${$a[-1]} eq '1', "in-place reverse strengthens weak reference"; + ok defined $a[2] && ${$a[2]} eq '3', "in-place reverse strengthens weak reference in the middle"; +} |