---------------------------------------- > Date: Wed, 25 Sep 2013 12:14:22 -0700 > Subject: Re: Avoid using PL_na with newSVpv > From: j...@activestate.com > To: kaffeeti...@gmx.de > CC: perl-xs@perl.org > > On Wed, Sep 25, 2013 at 12:04 PM, Torsten Schoenfeld <kaffeeti...@gmx.de> > wrote: >> Probably not. But <http://grep.cpan.me/?q=newSVpv.*PL_na> does show >> quite a few hits, only roughly half of which are mine. Since the bugs >> this causes are hard to diagnose, I thought a public service >> announcement is appropriate. > > Hmm, maybe you should email the maintainers of those modules directly > (or file bugs), if you have the time? perl-xs is kind of an obscure > list, so it is unlikely they will actually see this thread. > >> I think I simply assumed that "na" stood for "not available". So I took >> PL_na as a readability-improving alias for zero. > > I think in this case it means "not applicable", meaning "I don't care > what the value is". > > Cheers, > -Jan
I've thought for having, on 32 bit perl builds ONLY due to ABI issues, remove " STRLEN *const lp" from "Perl_sv_2pv_flags" and instead have it ALWAYS return the length in the return value. struct 2pvret { char * pvx; STRLEN len; } ______________________________ //fPerl_sv_2pv_flags sample struct 2pvret ret; if (SvPOKp(sv)) { ret.len = SvCUR(sv); if (flags & SV_MUTABLE_RETURN) { ret.pvx = SvPVX_mutable(sv); return ret; } if (flags & SV_CONST_RETURN) { ret.pvx = (char *)SvPVX_const(sv); return ret; } ret.pvx = SvPVX(sv); return ret; } ___________________________________ then in the caller in a STATIC INLINE func replace existing _____________________________________ #define SvPV_flags(sv, lp, flags) \ (SvPOK_nog(sv) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) ________________________________________ with ________________________________________ #define SvPV_flags(sv, lp, flags) SvPV_flags_real(sv, &lp, flags) STATIC INLINE char * SvPV_flags_real (SV * sv, STRLEN *const lp, const I32 flags) { if(SvPOK_nog(sv)) { *lp = SvCUR(sv); return SvPVX(sv); } else { struct 2pvret ret = sv_2pv_flags(sv, flags); *lp = ret.len; return ret.pvx; } } ______________________________________ When the above is inlined, all the copies and &s will be optimized away. the length will come back in volatile register edx. The char * will come back in eax as it always has. If the caller doesn't want length, it can just assign something else to edx immediately. There is no reason to reserve a C stack location to do &, in the rare case that 2pv_flags needs to be called. I tried this a while ago, using so much inlining that 2pv_flags become undebuggable since it was reinterfaced into the return struct by value. It saved like 1 KB of machine code in perl519.dll when I tried it,