From c29d9672c899b5f5d4cb3df248b777d06f5aea3b Mon Sep 17 00:00:00 2001 From: bulk88 Date: Wed, 19 Mar 2025 10:33:14 -0400 Subject: [PATCH] mPUSHn()/mPUSHi()/mPUSHu() convert from slow sv_set() to newSV()+2mortal() commit d82b684cd82 - Apr 30 2004 - Steve Hay Document limitations in PUSHi et al macros and add new mPUSHi et al macros which is day 1 of these macros, introduced this not ideal pattern doing "sv_setiv(PUSHmortal,)". sv_set*() funcs are much more complex/more work at runtime, since they must undo *everything* prior in the SV* and maybe upgrade the body and copy over fields from the prev "body[less]". newSV*() funcs dont have to do that. sv_2mortal() is very small and light weight internally, so rmving sv_newmortal() then adding sv_2mortal() isn't a problem, but for full disclosure, this commit makes better macros mPUSHn()/mPUSHi()/mPUSHu() than before, but this commit isn't perfect. sv_2mortal() is public api, and while it has exactly 1 conditional fn call in it (stack grower), it is a little bit heavier and does more work than a perfection hand written solution (see PUSH_EXTEND_MORTAL__SV_C). sv_2mortal() contains 4 branches, PUSH_EXTEND_MORTAL__SV_C has 1 branch. Another benefit of this commit is XS code that looks like if(r=c_syscall()) PUSHs(sv_2mortal(newSViv(r))); is better than if(r=c_syscall()) sv = newSV(); PUSHs(sv); sv_setiv(r); b/c var r, will effortlessly flow from the volatile retval register to a volatile outgoing "C stk" register (xfering control to newSViv()) and doesn't need to be save/restored from a non-vol storage location to preserve var r around a extern linked C fn. The 2004 commit above also has a same title medium sized P5P thread. This 2004 patch doesn't have a spotless history as a patch, and it went through multiple revisions b/c of typos and mistakes at the time, until it was decided to publish it. That commit probably did the "sv_setiv(PUSHmortal,)" pattern b/c of copy pasting from the existing TARG macros. And the commit is an improvement/fix for flaws or unfriendlyness that TARG macros had. --- pp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pp.h b/pp.h index 4bfdc32f8f6d..6371c1b5b754 100644 --- a/pp.h +++ b/pp.h @@ -568,9 +568,9 @@ Does not use C. See also C>, C> and C>. #define PUSHmortal PUSHs(sv_newmortal()) #define mPUSHp(p,l) PUSHs(newSVpvn_flags((p), (l), SVs_TEMP)) #define mPUSHpvs(s) mPUSHp("" s "", sizeof(s)-1) -#define mPUSHn(n) sv_setnv(PUSHmortal, (NV)(n)) -#define mPUSHi(i) sv_setiv(PUSHmortal, (IV)(i)) -#define mPUSHu(u) sv_setuv(PUSHmortal, (UV)(u)) +#define mPUSHn(n) mPUSHs(newSVnv((NV)(n))) +#define mPUSHi(i) mPUSHs(newSViv((IV)(i))) +#define mPUSHu(u) mPUSHs(newSVuv((UV)(u))) #define mXPUSHs(s) XPUSHs(sv_2mortal(s)) #define XPUSHmortal XPUSHs(sv_newmortal())