develooper Front page | perl.perl5.porters | Postings from March 2014

New API to store symbol names along pointers to symbols shared libs

Thread Next
Reini Urban
March 26, 2014 18:49
New API to store symbol names along pointers to symbols shared libs
Message ID:
Net::DNS used to crash with perlcc when thawing the ref of the PVMG
pointing to Encode::XS &ascii_encoding
This was

We couldn't fix Net::DNS, I rather worked around it in perlcc with
and in encode with

Now I'm trying to generally fix it for XS modules which store ptrs
to their structs in their objects and want to support thawing those pointers
when they are initialized at compile-time. Those compile-time ptrs will be
different to the pointers needed at run-time when being compiled.
(perlcc or later udump)

I came up with the solution to store the symbol name along the IV for
the ptr in the PV
slot with only the SVp_POK set (not SVp_POK), SvLEN being 0, and the
stash should be
enough to identify and restore this symbol at run-time.

i.e. freeze (IV + PV):
    HV *stash = gv_stashpv("Encode::XS", TRUE);
    SV *iv    = newSViv(PTR2IV(enc));
    SV *sv    = sv_bless(newRV_noinc(iv),stash);
    SvFLAGS(iv) |= SVp_POK;
    SvPVX(iv) = name;

This was previously (IV only):
    HV *stash = gv_stashpv("Encode::XS", TRUE);
    SV *sv    = sv_bless(newRV_noinc(newSViv(PTR2IV(enc))),stash);

and the thaw for the simple $Config{i_dlfcn} and $Config{d_dlopen} case:
 #include <dlfcn.h>
 void *handle, *ptr;
 char *name = "ascii_encoding";
 handle = dlopen(sofile("Encode"), RTLD_NOW|RTLD_NOLOAD);
 ptr = dlsym(handle, name);
 xpvmg_list[0].xiv_iv = PTR2IV(ptr);

I hope you get the idea.
This is very rarely needed, so far the only case in the wild was
Net::DNS which used
use constant ASCII => eval {
        require Encode;
        Encode::find_encoding('ASCII');                         #
return encoding object
} || 0;
compile-time ASCII allowed constant folding along several places in
the resolver.

But since storing arbitrary ptrs in such PVMG is pretty common, it
would be beneficial to
store the symbol name of the shared library also.
This is not needed for IO or process modules since such side-effects
are commonly not thawable.
The only usage is remapping of external symbol in shared libs, and
this is the common use case
which is implemented in all major LISPs in (save-image).

I already hear "thaw-hook as in Storable". But this is not needed for now.

I envision the API like:

/* newOBJ_ext stores the ptr to an external symbol (struct, function)
in a shared library
 * in a blessed reference to an IV,  and optionnaly allows thawing of
the symbol of via
 * dlsym for perlcc.
 * name can be a static const char * */
SV *sv    = newOBJ_ext(stash, ptr, name);

SV *newOBJ_ext(HV *stash, void *ptr, char *name) {
    SV *iv    = newSViv(PTR2IV(ptr));
    SV *sv    = sv_bless(newRV_noinc(iv),stash);
    SvFLAGS(iv) |= SVp_POK;
    SvPVX(iv) = name;
    return sv;
Reini Urban

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About