package Data::Dumper::ToXS;
-our (%ix, %seen);
+our (%ix, %seen, $weaken);
sub _newix { $_[0].'['.($ix{$_[0]}++).']' }
sub _getglob { \*{$_[0]} }
use B qw(svref_2object cstring);
-use Scalar::Util qw(refaddr);
+use Scalar::Util qw(refaddr isweak);
use Moo;
has target_package => (is => 'ro', required => 1);
my ($self, $name, $ref) = @_;
local %ix = map +($_ => 0), qw(av hv sv);
local %seen;
+ local $weaken = '';
my $first = _newix('sv');
my $body = $self->_dump_svrv($first, $ref);
my $vars = join '', map +(
<<"END";
SV * ${name} (pTHX)
{
-${vars}${body} return ${first};
+${vars}${body}${weaken} return ${first};
}
END
}
sub _dump_svrv {
my ($self, $ix, $ref) = @_;
my $r = ref($ref);
+ $weaken .= " sv_rvweaken(${ix});\n" if isweak($_[2]);
if ($seen{$ref}) {
# already seen this reference so make a copy
" ${ix} = newSVsv($seen{$ref});\n";
use Test::More;
use Data::Dumper::ToXS::Test;
use Data::Dumper;
+use Devel::Peek qw(SvREFCNT);
+use Scalar::Util qw(isweak);
my @fix = do 't/fixtures.pl' or die "t/fixtures.pl: $@";
is($l, $d, "Round tripped ${\$f->[0]} ok");
}
+{
+ my $r = $result{weaken_1};
+ ok(isweak($r->[1]), 'Weak element is weak');
+ is(SvREFCNT(${$r->[1]}), 2, 'Refcount of target correct');
+}
+
done_testing;
# disable the "Useless use of anonymous list ([]) in void context"
# warning so we can perl -c this file during development
no warnings 'void';
+use Scalar::Util qw(weaken);
[
data_structure =>
{
do { sub DDXSTest::foo { 'DDXSTest::foo' } () },
[
global_sub => { foo => \&DDXSTest::foo }
-];
+],
+[
+ weaken_1 => do {
+ my $x = 1;
+ my $y = [ \$x, \$x, \$x ];
+ weaken($y->[1]);
+ $y;
+ }
+],
+[
+ weaken_0 => do {
+ my $x = 1;
+ my $y = [ \$x, \$x, \$x ];
+ weaken($y->[0]);
+ $y;
+ }
+]