-
Notifications
You must be signed in to change notification settings - Fork 571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
op.c: slim down const_av_xsub const_sv_xsub XSUB.h: add GetXSTARG() #23156
base: blead
Are you sure you want to change the base?
Conversation
op.c
Outdated
U8 gm; | ||
SV * retsv; | ||
SSize_t av_cur; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all be defined at or closer to point of first use.
XSUB.h
Outdated
/* A faster, more efficient variant of C<dXSTARG>. Similar to the optree's | ||
GETTARGET, but "specialized" for XSUBs written by core or written by CPAN. | ||
Do not evaluate this macro multiple times. Save the result of this macro to | ||
a C<SV*> var. You must test the returned value for C<NULL> and procede | ||
accordingly. Do not make any assumptions on why did or did not get NULL | ||
from this macro. This macro is not a substitute for using L<GIMME_V>. | ||
The non-NULL or NULL result of this macro has no correlation to what | ||
C<@_> context, the caller PP/XS sub, has requested from your XSUB through | ||
C<GIMME_V>. | ||
|
||
Assume C<GIMME_V> can return <G_VOID> while at the same time C<GetXSTARG> | ||
returns non-NULL. Also assume C<if (!(sv = GetXSTARG()) && GIMME_V == G_SCALAR)> | ||
can happen and therefore you very likely will need to allocate a new C<SV*> | ||
and mortalize it. It is discouraged and probably a bug, for an XSUB to | ||
bump the C<SvREFCNT(sv)> on C<TARG> and save the C<SV*> for later use. | ||
Do not make assumptions about C<TARG>'s C<SvREFCNT>, or what is the outer | ||
container that really the C<SV*>. Something else inside the interpreter | ||
which is unspecified, owns C<SV* TARG>, and unspecified caller, probably | ||
wants you to write into this C<SV*> as an lval, vs you doing a less | ||
efficient C<sv_newmortal()>/C<sv_2mortal(newSVxxxv())>, and later on the | ||
unspecified caller has to call <sv_setsv()>, and let the mortal stack dispose | ||
of your short lived <SV*>. | ||
|
||
Although this is undocumented and private to the interpreter and you may not | ||
write code that is aware of this private implementation detail. Keep in | ||
mind the interpreter uses the C<SV* TARG> concept for both input and/or output | ||
in various places between parts of itself and might be using C<SV* TARG> as | ||
lvalue scratch pad in a loop. | ||
|
||
Remember that the C<SV*> from C<dXSTARG> or C<GetXSTARG>, might be C<SvOK()> | ||
and have stale prior contents that you need to wipe or free. C<sv_setxxx()> | ||
functions will always do this for you. There is no guarentee the <SV*> | ||
from C<dXSTARG> or C<GetXSTARG> will be set to C<undef> when you get it. | ||
If you need to return C<undef>, you have 2 choices. Don't fetch and | ||
don't use C<TARG>, and push C<&PL_sv_undef> on the stack. The other choices | ||
you have is to call, sorted most efficient to least efficient: | ||
|
||
sv_setsv_undef(my_targ); SvSETMAGIC(my_targ); | ||
sv_setpv_mg(my_targ, NULL); | ||
sv_setsv_mg(my_targ, NULL); | ||
sv_setsv_mg(my_targ, &PL_sv_undef); //more readable | ||
|
||
Also consider, there is no clear guidance for this. Do you think you the | ||
PP or XS caller, that called your XSUB, if it is interested in getting a | ||
C<@_> return value in the first place. Is the caller going to write it as | ||
a true/false check, like C<if(do_xsub()) {0;}>, or will it write | ||
C<my $result = do_xsub();> and capture your return value for future use. | ||
The first probably don't set up a TARG for your to use. The 2nd probably | ||
will, but there are no guarentees it will set one up ahead of time. | ||
|
||
Returning address C<&PL_sv_undef> is much faster than C<sv_newmortal()> or | ||
C<sv_set_undef()>. C<sv_set_undef()> is faster than the caller later on | ||
doing a C<sv_setsv()>. C<sv_setsv()> has a quick bailout shortcut in it | ||
if src and dest C<SV*>s are the same addr. | ||
|
||
There is also no guarentee about what its C<SvTYPE()> is. | ||
Always assume it is of type <SVt_NULL>, and it has no SV body until you | ||
you test its type and possibly call C<SvUPGRADE> or <sv_setiv>/C<sv_setpvn> | ||
on it. There is no guarentee C<SvANY()> is non-NULL or C<SvANY()> contains | ||
a valid address or points to initialized memory. There is no guarentee | ||
C<SvTYPE()> is at minimum C<SVt_IV> and reading C<SvIVX()> won't SEGV. */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Way too much. Just say what it does, mention the SV may not be fresh and you're done.
Any more belongs in pod/something.pod
, somewhere.
If this is intended for use only by core it should be guarded by #ifdef PERL_CORE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Way too much. Just say what it does, mention the SV may not be fresh and you're done.
Agree. Revision 1's api desc is too many bytes getting sent through the CPP and too many bytes to PgDn through.
Revision 2 inside XSUB.h, on my side is currently
/* A faster, more efficient variant of C<dXSTARG>. Similar to the optree's
GETTARGET, but "specialized" for XSUBs written by core or written by CPAN.
The benefit of C<GetXSTARG> over C<dXSTARG> is that C<GetXSTARG> will return
C<NULL> if a targ C<SV *> isn't currently available and lets the user decide
how to go forward. Meanwhile C<dXSTARG> will always internally call
C<sv_newmortal()> if a targ C<SV *> isn't available at that moment.
Do not evaluate this macro multiple times. Save the result of this macro to
a C<SV*> var.
Just like C<dXSTARG>, the C<SV *> returned by C<GetXSTARG> may have stale
prior contents in it. */
Any more belongs in
pod/something.pod
, somewhere.
Agree.
If this is intended for use only by core it should be guarded by
#ifdef PERL_CORE
.
Agree. I want to see other ppl usage before calling something public API. My definition of "other people usage" is a minimum of 1 other person somewhere typing it in and clicking save. My api doc is written in a way, that Im leaving a provision, that macro GetXSTARG()
could become a static inline or a libperl exported function in the future if there is some reason to do so.
GIMME_V used to be a horrible multi eval mouse trap perl 5.1X era. Its been optimized to a macro/fn call free inline in modern perl. CvGV() and GvSV() used to be fast func call free macros in 5.8 and older. In modern perl they are horrible multi eval mouse traps (vivifiers/malloc/getter methods). Dangerous ultra-fast macros, use-brain-thinking-required fast macros/fast static inlines, and full service heavy weight exported functions all need to be labeled and documented correctly from day 1. Which one causes subtle heap corruption and SEGVs, and which one tells you through STDERR $@
what you did wrong, every person needs to know that ahead of time.
Do you or anyone else know what file to hide the pod I wrote in? I want it to be inside pod/perlintern.pod
, but that file can't be hand edited, and I don't want the CPP to see my pod text. I strace
d autodoc.pl
but I still can't find anywhere to put my pod text. If I put it in a .h
or .c
, the CPP will see it, no good. If I put it in perlguts.pod
, now its public API, no good. pod/perlhack.pod
looks like someone talking while sipping a beer. Its writing style is edutainment or learning to code in C by watching Instagram videos. Its my last resort .pod
file wise where to put a formal API description.
Maybe this GH PR is enough "POD" just by itself since P5P's GH bug tracker is a perm un-deleteable archive just like RT was? Correct?
I'm not sure if your quote above will loose its code citation to my "failed" commit, when I delete or repush the commit/branch on my side.
strace log from autodoc.pl. Click to Expand.
``` C:\sources\perl5\amigaos4 C:\sources\perl5\amigaos4\amigaio.c C:\sources\perl5\amigaos4\amigaio.h C:\sources\perl5\amigaos4\amigaos.c C:\sources\perl5\amigaos4\amigaos.h C:\sources\perl5\autodoc.pl C:\sources\perl5\av.c C:\sources\perl5\av.h C:\sources\perl5\builtin.c C:\sources\perl5\caretx.c C:\sources\perl5\class.c C:\sources\perl5\cop.h C:\sources\perl5\cpan\AutoLoader\lib\HeaderParser.pm C:\sources\perl5\cpan\ExtUtils-Constant\lib\HeaderParser.pm C:\sources\perl5\cpan\ExtUtils-Install\lib\HeaderParser.pm C:\sources\perl5\cpan\ExtUtils-MakeMaker\lib\HeaderParser.pm C:\sources\perl5\cpan\ExtUtils-Manifest\lib\HeaderParser.pm C:\sources\perl5\cpan\ExtUtils-PL2Bat\lib\HeaderParser.pm C:\sources\perl5\cpan\File-Path\lib\HeaderParser.pm C:\sources\perl5\cpan\Getopt-Long\lib\HeaderParser.pm C:\sources\perl5\cpan\parent\lib\HeaderParser.pm C:\sources\perl5\cpan\Text-ParseWords\lib\HeaderParser.pm C:\sources\perl5\cpan\Text-Tabs\lib\HeaderParser.pm C:\sources\perl5\cpan\version\lib\HeaderParser.pm C:\sources\perl5\cv.h C:\sources\perl5\cygwin C:\sources\perl5\cygwin\cygwin.c C:\sources\perl5\deb.c C:\sources\perl5\dist C:\sources\perl5\dist\base\lib\HeaderParser.pm C:\sources\perl5\dist\Carp\lib\HeaderParser.pm C:\sources\perl5\dist\constant\lib\HeaderParser.pm C:\sources\perl5\dist\Exporter\lib\HeaderParser.pm C:\sources\perl5\dist\ExtUtils-ParseXS C:\sources\perl5\dist\ExtUtils-ParseXS\lib C:\sources\perl5\dist\ExtUtils-ParseXS\lib\HeaderParser.pm C:\sources\perl5\dist\ExtUtils-ParseXS\lib\perlxs.pod C:\sources\perl5\dist\PathTools\HeaderParser.pm C:\sources\perl5\dist\PathTools\lib\HeaderParser.pm C:\sources\perl5\dist\Term-ReadLine\lib\HeaderParser.pm C:\sources\perl5\doio.c C:\sources\perl5\doop.c C:\sources\perl5\dosish.h C:\sources\perl5\dquote.c C:\sources\perl5\dump.c C:\sources\perl5\ebcdic_tables.h C:\sources\perl5\embed.fnc C:\sources\perl5\embed.h C:\sources\perl5\embedvar.h C:\sources\perl5\EXTERN.h C:\sources\perl5\ext\File-Find\lib\HeaderParser.pm C:\sources\perl5\ext\re\HeaderParser.pm C:\sources\perl5\fakesdio.h C:\sources\perl5\feature.h C:\sources\perl5\form.h C:\sources\perl5\generate_uudmap.c C:\sources\perl5\globals.c C:\sources\perl5\gv.c C:\sources\perl5\gv.h C:\sources\perl5\haiku C:\sources\perl5\haiku\haikuish.h C:\sources\perl5\handy.h C:\sources\perl5\HeaderParser.pm C:\sources\perl5\hints C:\sources\perl5\hints\t001.c C:\sources\perl5\hv.c C:\sources\perl5\hv.h C:\sources\perl5\hv_func.h C:\sources\perl5\hv_macro.h C:\sources\perl5\inline.h C:\sources\perl5\INTERN.h C:\sources\perl5\intrpvar.h C:\sources\perl5\invlist_inline.h C:\sources\perl5\iperlsys.h C:\sources\perl5\keywords.c C:\sources\perl5\keywords.h C:\sources\perl5\l1_char_class_tab.h C:\sources\perl5\lib C:\sources\perl5\lib\buildcustomize.pl C:\sources\perl5\lib\Carp.pm C:\sources\perl5\lib\Config.pm C:\sources\perl5\lib\constant.pm C:\sources\perl5\lib\CORE.pod C:\sources\perl5\lib\DynaLoader.pm C:\sources\perl5\lib\Exporter C:\sources\perl5\lib\Exporter.pm C:\sources\perl5\lib\Exporter\Heavy.pm C:\sources\perl5\lib\Fcntl.pm C:\sources\perl5\lib\File C:\sources\perl5\lib\File\Compare.pm C:\sources\perl5\lib\HeaderParser.pm C:\sources\perl5\lib\integer.pm C:\sources\perl5\lib\Internals.pod C:\sources\perl5\lib\overloading.pm C:\sources\perl5\lib\re.pm C:\sources\perl5\lib\Storable.pm C:\sources\perl5\lib\strict.pm C:\sources\perl5\lib\Symbol.pm C:\sources\perl5\lib\Text C:\sources\perl5\lib\Text\Tabs.pm C:\sources\perl5\lib\Text\Wrap.pm C:\sources\perl5\lib\vars.pm C:\sources\perl5\lib\warnings C:\sources\perl5\lib\warnings.pm C:\sources\perl5\lib\warnings\register.pm C:\sources\perl5\lib\XSLoader.pm C:\sources\perl5\locale.c C:\sources\perl5\locale_table.h C:\sources\perl5\malloc.c C:\sources\perl5\malloc_ctl.h C:\sources\perl5\MANIFEST C:\sources\perl5\mathoms.c C:\sources\perl5\metaconfig.h C:\sources\perl5\mg.c C:\sources\perl5\mg.h C:\sources\perl5\mg_raw.h C:\sources\perl5\mg_vtable.h C:\sources\perl5\miniperl.exe C:\sources\perl5\miniperl.exe.Local C:\sources\perl5\miniperlmain.c C:\sources\perl5\mro_core.c C:\sources\perl5\mydtrace.h C:\sources\perl5\nostdio.h C:\sources\perl5\numeric.c C:\sources\perl5\op.c C:\sources\perl5\op.h C:\sources\perl5\opcode.h C:\sources\perl5\opnames.h C:\sources\perl5\op_reg_common.h C:\sources\perl5\os2 C:\sources\perl5\os2\dlfcn.h C:\sources\perl5\os2\dl_os2.c C:\sources\perl5\os2\OS2 C:\sources\perl5\os2\os2.c C:\sources\perl5\os2\os2ish.h C:\sources\perl5\os2\os2thread.h C:\sources\perl5\os2\OS2\OS2-ExtAttr C:\sources\perl5\os2\OS2\OS2-ExtAttr\myea.h C:\sources\perl5\os2\perlrexx.c C:\sources\perl5\overload.h C:\sources\perl5\pad.c C:\sources\perl5\pad.h C:\sources\perl5\parser.h C:\sources\perl5\patchlevel.h C:\sources\perl5\peep.c C:\sources\perl5\perl.c C:\sources\perl5\perl.h C:\sources\perl5\perlapi.h C:\sources\perl5\perlio.c C:\sources\perl5\perlio.h C:\sources\perl5\perliol.h C:\sources\perl5\perlsdio.h C:\sources\perl5\perlstatic.h C:\sources\perl5\perlvars.h C:\sources\perl5\perly.c C:\sources\perl5\perly.h C:\sources\perl5\perl_inc_macro.h C:\sources\perl5\perl_langinfo.h C:\sources\perl5\perl_siphash.h C:\sources\perl5\plan9 C:\sources\perl5\plan9\arpa C:\sources\perl5\plan9\arpa\inet.h C:\sources\perl5\plan9\math.h C:\sources\perl5\plan9\plan9.c C:\sources\perl5\plan9\plan9ish.h C:\sources\perl5\pod C:\sources\perl5\pod\perl.pod C:\sources\perl5\pod\perl5004delta.pod C:\sources\perl5\pod\perl5005delta.pod C:\sources\perl5\pod\perl5100delta.pod C:\sources\perl5\pod\perl5101delta.pod C:\sources\perl5\pod\perl5120delta.pod C:\sources\perl5\pod\perl5121delta.pod C:\sources\perl5\pod\perl5122delta.pod C:\sources\perl5\pod\perl5123delta.pod C:\sources\perl5\pod\perl5124delta.pod C:\sources\perl5\pod\perl5125delta.pod C:\sources\perl5\pod\perl5140delta.pod C:\sources\perl5\pod\perl5141delta.pod C:\sources\perl5\pod\perl5142delta.pod C:\sources\perl5\pod\perl5143delta.pod C:\sources\perl5\pod\perl5144delta.pod C:\sources\perl5\pod\perl5160delta.pod C:\sources\perl5\pod\perl5161delta.pod C:\sources\perl5\pod\perl5162delta.pod C:\sources\perl5\pod\perl5163delta.pod C:\sources\perl5\pod\perl5180delta.pod C:\sources\perl5\pod\perl5181delta.pod C:\sources\perl5\pod\perl5182delta.pod C:\sources\perl5\pod\perl5184delta.pod C:\sources\perl5\pod\perl5200delta.pod C:\sources\perl5\pod\perl5201delta.pod C:\sources\perl5\pod\perl5202delta.pod C:\sources\perl5\pod\perl5203delta.pod C:\sources\perl5\pod\perl5220delta.pod C:\sources\perl5\pod\perl5221delta.pod C:\sources\perl5\pod\perl5222delta.pod C:\sources\perl5\pod\perl5223delta.pod C:\sources\perl5\pod\perl5224delta.pod C:\sources\perl5\pod\perl5240delta.pod C:\sources\perl5\pod\perl5241delta.pod C:\sources\perl5\pod\perl5242delta.pod C:\sources\perl5\pod\perl5243delta.pod C:\sources\perl5\pod\perl5244delta.pod C:\sources\perl5\pod\perl5260delta.pod C:\sources\perl5\pod\perl5261delta.pod C:\sources\perl5\pod\perl5262delta.pod C:\sources\perl5\pod\perl5263delta.pod C:\sources\perl5\pod\perl5280delta.pod C:\sources\perl5\pod\perl5281delta.pod C:\sources\perl5\pod\perl5282delta.pod C:\sources\perl5\pod\perl5283delta.pod C:\sources\perl5\pod\perl5300delta.pod C:\sources\perl5\pod\perl5301delta.pod C:\sources\perl5\pod\perl5302delta.pod C:\sources\perl5\pod\perl5303delta.pod C:\sources\perl5\pod\perl5320delta.pod C:\sources\perl5\pod\perl5321delta.pod C:\sources\perl5\pod\perl5340delta.pod C:\sources\perl5\pod\perl5341delta.pod C:\sources\perl5\pod\perl5342delta.pod C:\sources\perl5\pod\perl5343delta.pod C:\sources\perl5\pod\perl5360delta.pod C:\sources\perl5\pod\perl5361delta.pod C:\sources\perl5\pod\perl5362delta.pod C:\sources\perl5\pod\perl5363delta.pod C:\sources\perl5\pod\perl5380delta.pod C:\sources\perl5\pod\perl5381delta.pod C:\sources\perl5\pod\perl5382delta.pod C:\sources\perl5\pod\perl5383delta.pod C:\sources\perl5\pod\perl5400delta.pod C:\sources\perl5\pod\perl5401delta.pod C:\sources\perl5\pod\perl5410delta.pod C:\sources\perl5\pod\perl5411delta.pod C:\sources\perl5\pod\perl5412delta.pod C:\sources\perl5\pod\perl5413delta.pod C:\sources\perl5\pod\perl5414delta.pod C:\sources\perl5\pod\perl5415delta.pod C:\sources\perl5\pod\perl5416delta.pod C:\sources\perl5\pod\perl5417delta.pod C:\sources\perl5\pod\perl5418delta.pod C:\sources\perl5\pod\perl5419delta.pod C:\sources\perl5\pod\perl561delta.pod C:\sources\perl5\pod\perl56delta.pod C:\sources\perl5\pod\perl581delta.pod C:\sources\perl5\pod\perl582delta.pod C:\sources\perl5\pod\perl583delta.pod C:\sources\perl5\pod\perl584delta.pod C:\sources\perl5\pod\perl585delta.pod C:\sources\perl5\pod\perl586delta.pod C:\sources\perl5\pod\perl587delta.pod C:\sources\perl5\pod\perl588delta.pod C:\sources\perl5\pod\perl589delta.pod C:\sources\perl5\pod\perl58delta.pod C:\sources\perl5\pod\perlapi.pod C:\sources\perl5\pod\perlapi.pod-new C:\sources\perl5\pod\perlapio.pod C:\sources\perl5\pod\perlartistic.pod C:\sources\perl5\pod\perlbook.pod C:\sources\perl5\pod\perlcall.pod C:\sources\perl5\pod\perlcheat.pod C:\sources\perl5\pod\perlclass.pod C:\sources\perl5\pod\perlclassguts.pod C:\sources\perl5\pod\perlclib.pod C:\sources\perl5\pod\perlcommunity.pod C:\sources\perl5\pod\perldata.pod C:\sources\perl5\pod\perldbmfilter.pod C:\sources\perl5\pod\perldebguts.pod C:\sources\perl5\pod\perldebtut.pod C:\sources\perl5\pod\perldebug.pod C:\sources\perl5\pod\perldelta.pod C:\sources\perl5\pod\perldeprecation.pod C:\sources\perl5\pod\perldiag.pod C:\sources\perl5\pod\perldocstyle.pod C:\sources\perl5\pod\perldsc.pod C:\sources\perl5\pod\perldtrace.pod C:\sources\perl5\pod\perlebcdic.pod C:\sources\perl5\pod\perlembed.pod C:\sources\perl5\pod\perlexperiment.pod C:\sources\perl5\pod\perlfilter.pod C:\sources\perl5\pod\perlfork.pod C:\sources\perl5\pod\perlform.pod C:\sources\perl5\pod\perlfunc.pod C:\sources\perl5\pod\perlgit.pod C:\sources\perl5\pod\perlgov.pod C:\sources\perl5\pod\perlgpl.pod C:\sources\perl5\pod\perlguts.pod C:\sources\perl5\pod\perlhack.pod C:\sources\perl5\pod\perlhacktips.pod C:\sources\perl5\pod\perlhacktut.pod C:\sources\perl5\pod\perlhist.pod C:\sources\perl5\pod\perlintern.pod C:\sources\perl5\pod\perlintern.pod-new C:\sources\perl5\pod\perlinterp.pod C:\sources\perl5\pod\perlintro.pod C:\sources\perl5\pod\perliol.pod C:\sources\perl5\pod\perlipc.pod C:\sources\perl5\pod\perllexwarn.pod C:\sources\perl5\pod\perllocale.pod C:\sources\perl5\pod\perllol.pod C:\sources\perl5\pod\perlmod.pod C:\sources\perl5\pod\perlmodinstall.pod C:\sources\perl5\pod\perlmodstyle.pod C:\sources\perl5\pod\perlmroapi.pod C:\sources\perl5\pod\perlnewmod.pod C:\sources\perl5\pod\perlnumber.pod C:\sources\perl5\pod\perlobj.pod C:\sources\perl5\pod\perlootut.pod C:\sources\perl5\pod\perlop.pod C:\sources\perl5\pod\perlopentut.pod C:\sources\perl5\pod\perlpacktut.pod C:\sources\perl5\pod\perlperf.pod C:\sources\perl5\pod\perlpod.pod C:\sources\perl5\pod\perlpodspec.pod C:\sources\perl5\pod\perlpodstyle.pod C:\sources\perl5\pod\perlpolicy.pod C:\sources\perl5\pod\perlport.pod C:\sources\perl5\pod\perlpragma.pod C:\sources\perl5\pod\perlre.pod C:\sources\perl5\pod\perlreapi.pod C:\sources\perl5\pod\perlrebackslash.pod C:\sources\perl5\pod\perlrecharclass.pod C:\sources\perl5\pod\perlref.pod C:\sources\perl5\pod\perlreftut.pod C:\sources\perl5\pod\perlreguts.pod C:\sources\perl5\pod\perlrequick.pod C:\sources\perl5\pod\perlreref.pod C:\sources\perl5\pod\perlretut.pod C:\sources\perl5\pod\perlrun.pod C:\sources\perl5\pod\perlsec.pod C:\sources\perl5\pod\perlsecpolicy.pod C:\sources\perl5\pod\perlsource.pod C:\sources\perl5\pod\perlstyle.pod C:\sources\perl5\pod\perlsub.pod C:\sources\perl5\pod\perlsyn.pod C:\sources\perl5\pod\perlthrtut.pod C:\sources\perl5\pod\perltie.pod C:\sources\perl5\pod\perltrap.pod C:\sources\perl5\pod\perlunicode.pod C:\sources\perl5\pod\perlunicook.pod C:\sources\perl5\pod\perlunifaq.pod C:\sources\perl5\pod\perluniintro.pod C:\sources\perl5\pod\perlunitut.pod C:\sources\perl5\pod\perlutil.pod C:\sources\perl5\pod\perlvar.pod C:\sources\perl5\pod\perlvms.pod C:\sources\perl5\Porting C:\sources\perl5\Porting\docs-team-charter.pod C:\sources\perl5\Porting\epigraphs.pod C:\sources\perl5\Porting\how_to_write_a_perldelta.pod C:\sources\perl5\Porting\perldelta_template.pod C:\sources\perl5\Porting\pumpkin.pod C:\sources\perl5\Porting\README.pod C:\sources\perl5\Porting\release_managers_guide.pod C:\sources\perl5\Porting\release_schedule.pod C:\sources\perl5\Porting\security_template.pod C:\sources\perl5\Porting\timecheck.c C:\sources\perl5\Porting\timecheck2.c C:\sources\perl5\Porting\todo.pod C:\sources\perl5\Porting\vote_admin_guide.pod C:\sources\perl5\pp.c C:\sources\perl5\pp.h C:\sources\perl5\pp_ctl.c C:\sources\perl5\pp_hot.c C:\sources\perl5\pp_pack.c C:\sources\perl5\pp_proto.h C:\sources\perl5\pp_sort.c C:\sources\perl5\pp_sys.c C:\sources\perl5\proto.h C:\sources\perl5\qnx C:\sources\perl5\qnx\qnx.c C:\sources\perl5\reentr.c C:\sources\perl5\reentr.h C:\sources\perl5\regcharclass.h C:\sources\perl5\regcomp.c C:\sources\perl5\regcomp.h C:\sources\perl5\regcomp_debug.c C:\sources\perl5\regcomp_internal.h C:\sources\perl5\regcomp_invlist.c C:\sources\perl5\regcomp_study.c C:\sources\perl5\regcomp_trie.c C:\sources\perl5\regen C:\sources\perl5\regen\embed_lib.pl C:\sources\perl5\regen\HeaderParser.pm C:\sources\perl5\regen\opcodes C:\sources\perl5\regen\regen_lib.pl C:\sources\perl5\regexec.c C:\sources\perl5\regexp.h C:\sources\perl5\regexp_constants.h C:\sources\perl5\reginline.h C:\sources\perl5\regnodes.h C:\sources\perl5\run.c C:\sources\perl5\sbox32_hash.h C:\sources\perl5\scope.c C:\sources\perl5\scope.h C:\sources\perl5\scope_types.h C:\sources\perl5\sv.c C:\sources\perl5\sv.h C:\sources\perl5\sv_inline.h C:\sources\perl5\t C:\sources\perl5\taint.c C:\sources\perl5\thread.h C:\sources\perl5\time64.c C:\sources\perl5\time64.h C:\sources\perl5\time64_config.h C:\sources\perl5\toke.c C:\sources\perl5\t\lib C:\sources\perl5\t\lib\h2ph.h C:\sources\perl5\unicode_constants.h C:\sources\perl5\universal.c C:\sources\perl5\unixish.h C:\sources\perl5\uni_keywords.h C:\sources\perl5\utf8.c C:\sources\perl5\utf8.h C:\sources\perl5\utfebcdic.h C:\sources\perl5\util.c C:\sources\perl5\util.h C:\sources\perl5\vms C:\sources\perl5\vms\munchconfig.c C:\sources\perl5\vms\vms.c C:\sources\perl5\vms\vmsish.h C:\sources\perl5\vos C:\sources\perl5\vos\vos.c C:\sources\perl5\vos\vosish.h C:\sources\perl5\vutil.c C:\sources\perl5\vutil.h C:\sources\perl5\warnings.h C:\sources\perl5\win32 C:\sources\perl5\win32\configure C:\sources\perl5\win32\configure\rt.c C:\sources\perl5\win32\fcrypt.c C:\sources\perl5\win32\full C:\sources\perl5\win32\full\config.h C:\sources\perl5\win32\include C:\sources\perl5\win32\include\arpa C:\sources\perl5\win32\include\arpa\inet.h C:\sources\perl5\win32\include\dirent.h C:\sources\perl5\win32\include\netdb.h C:\sources\perl5\win32\include\sys C:\sources\perl5\win32\include\sys\errno2.h C:\sources\perl5\win32\include\sys\socket.h C:\sources\perl5\win32\perlglob.c C:\sources\perl5\win32\perlhost.h C:\sources\perl5\win32\perllib.c C:\sources\perl5\win32\runperl.c C:\sources\perl5\win32\vdir.h C:\sources\perl5\win32\vmem.h C:\sources\perl5\win32\win32.c C:\sources\perl5\win32\win32.h C:\sources\perl5\win32\win32iop.h C:\sources\perl5\win32\win32sck.c C:\sources\perl5\win32\win32thread.c C:\sources\perl5\win32\win32thread.h C:\sources\perl5\XSUB.h C:\sources\perl5\zaphod32_hash.h ```8240f0a
to
a42385e
Compare
-don't use XSRETURN() macros, they use "unit of 1" relative offset "ax" and constantly reread global my_parl->Istack_base and constant rescale ax from unit of 1 to unit of 4/8 -don't use ST() macros for the same reason -in const_sv_xsub() use XSTARG if its available, but just put our long life SV* right on the PL stack if we can't write directly into the caller lval SV*. Don't do "sv_setsv(sv_newmortal(), ssv);" on missing XSTARG branch. Don't use dXSTARG; 50% chance there will be a 2nd!!! secret "sv_setsv(sv_newmortal(),rval)" or "newSVsv(rval)" right after this XSUB anyways, so just pass our SV* on stack instead of TWO "sv_setsv(sv_newmortal(), ssv);" statements executing in a row. const_av_xsub(): -if we will croak, do it ASAP once the minimum amount of data has been read from global memory, AV* is delivered through C function argument CV* cv, its not from the PL stack. So do the check and execute the no return before creating/reading/writing a ton of PL stack related global vars and C auto vars. -GetXSTARG() and GIMME_V() both dig inside PL_op, keep them together w/o any func calls in between such as EXTEND() so the CC can read OP* stored in PL_op only once -break apart Copy()'s overflow bounds checks so we can write a new "length" to global state before copying the large in bytes array, historically Perl has issues with letting PP end users code to keep running for severe overflows/heap corruption/CVE type stuff, eval{}, %SIG, tied, MG, sub END, etc. So do the asserts early before the actual memcpy or PUTBACK. -handle an empty/0 elems long AV* better, don't EXTEND(0), don't call extern libc memcpy with 0 size -don't keep re-reading the AV head and AV body and AvFILLp(av) over and over, func calls EXTEND() and memcpy() won't realloc the AV body ptr or modify the AvFILL member in the body struct XSUB.h: -add a version of dXSTARG where the user handles what to do, if parent frame didn't supply a SV* TARG for lval filling. This gets rid of the inefficient sv_newmortal() that is forced on users when there almost always better faster recipie of how to create a 0, 1, or G_LIST PL stack retval. &PL_sv_undef, newSVpvn_flags(SVs_TEMP), sv_2mortal(newSViv()), return your hash key's value SV* directly, etc. Macro undocumented until further notice, so it can gather some unofficial usage/CORE usage and some opinions regarding is it good or flawed.
a42385e
to
36beb19
Compare
-don't use XSRETURN() macros, they use "unit of 1" relative offset "ax"
and constantly reread global my_parl->Istack_base and constant rescale
ax from unit of 1 to unit of 4/8
-don't use ST() macros for the same reason
-in const_sv_xsub() use XSTARG if its available, but just put our long
life SV* right on the PL stack if we can't write directly into the
caller lval SV*. Don't do "sv_setsv(sv_newmortal(), ssv);" on missing
XSTARG branch. Don't use dXSTARG; 50% chance there will be a 2nd!!!
secret "sv_setsv(sv_newmortal(),rval)" or "newSVsv(rval)" right after
this XSUB anyways, so just pass our SV* on stack instead of TWO
"sv_setsv(sv_newmortal(), ssv);" statements executing in a row.
const_av_xsub():
-if we will croak, do it ASAP once the minimum amount of data has been
read from global memory, AV* is delivered through C function argument
CV* cv, its not from the PL stack. So do the check and execute the
no return before creating/reading/writing a ton of PL stack related
global vars and C auto vars.
-GetXSTARG() and GIMME_V() both dig inside PL_op, keep them together w/o
any func calls in between such as EXTEND() so the CC can read OP* stored
in PL_op only once
-break apart Copy()'s overflow bounds checks so we can write a new "length"
to global state before copying the large in bytes array, historically
Perl has issues with letting PP end users code to keep running for severe
overflows/heap corruption/CVE type stuff, eval{}, %SIG, tied, MG,
sub END, etc. So do the asserts early before the actual memcpy or PUTBACK.
-handle an empty/0 elems long AV* better, don't EXTEND(0), don't call
extern libc memcpy with 0 size
-don't keep re-reading the AV head and AV body and AvFILLp(av) over and
over, func calls EXTEND() and memcpy() won't realloc the AV body ptr or
modify the AvFILL member in the body struct
XSUB.h:
-add a version of dXSTARG where the user handles what to do, if parent
frame didn't supply a SV* TARG for lval filling. This gets rid of the
inefficient sv_newmortal() that is forced on users when there almost
always better faster recipie of how to create a 0, 1, or G_LIST PL
stack retval. &PL_sv_undef, newSVpvn_flags(SVs_TEMP),
sv_2mortal(newSViv()), return your hash key's value SV* directly, etc.
Macro undocumented until further notice, so it can gather some unofficial
usage/CORE usage and some opinions regarding is it good or flawed.
The POD for macro
GetXSTARG()
was already written in this PR, it just not being made public ATM but its POD already exists if it becomes public one day.PR doesn't add public API.