On Fri, Jun 06, 2025 at 07:27:55PM +0100, Gavin Smith wrote:
> In element_to_perl_hash, commit 359b73825d2 changed:
> 
> -      sv = newRV_inc ((SV *) e->parent->hv);
> -      hv_store (e->hv, "parent", strlen ("parent"), sv, HSH_parent);
> +      sv = SvREFCNT_inc ((SV *) e->parent->sv);
> +      hv_store (element_hv, "parent", strlen ("parent"), sv, HSH_parent);
> 
> So rather than creating a new reference and storing it in the hash, the same
> SV object is stored in the hash that is used elsewhere (including in element
> contents arrays).

That is expected.  What I didn't expect is what you write just below, that
assigning in Perl does not create a new SV.

> When you delete the hash entry for "parent" with 'delete', and then recreate
> it, you get a new SV that isn't shared with any other data structure.
> 
> To explain the problem another way, I believe that if you had XS code like:
> 
> HV *hv = newHV ();
> SV *sv = newSViv(7);
> hv_store (hv, "foo", strlen ("foo"), sv, 0);
> hv_store (hv, "bar", strlen ("bar"), sv, 0);
> 
> and then, in Perl code, did
> 
> $hv->{'foo'} = 8;
> 
> then $hv->{'bar'} would also change from 7 to 8.  (I haven't tested this.)

Indeed, that's the issue, thanks for the analysis.  What confused me is
that in Perl code, it does not happens that way, but I think that it is
because the Perl scalars are not the same as a SV in XS, the SV can be
shared in XS and keeps being shared when Perl code is applied, in Perl
it is not possible, the references are copied instead of being shared,
if I may say.  Using newRV_*inc creates a new SV each time, making the
previous code more similar to what happens in Perl code.

I found newSVsv, which seems to copy the SV, including the blessing and
the 'reference' to the HV, this could be an alternative to keeping the
HV in C and calling newRV and blessing each time a reference is needed.
I still need to check if there needs to be an adjustment of reference
counting.  Note that I switched to keeping the SV to avoid needing to
bless each SV created by newRV_*inc.

-- 
Pat

Reply via email to