summaryrefslogtreecommitdiff
path: root/gv.h
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2015-01-04 17:49:09 -0500
committerFather Chrysostomos <sprout@cpan.org>2015-01-06 06:39:33 -0800
commit819b139db33e2022424694e381422766903d4f65 (patch)
tree873f0454363c670d996af0389e6f85436806d84c /gv.h
parent070d3cb6f06f7c7f0a932b57616cd28061cb96c0 (diff)
downloadperl-819b139db33e2022424694e381422766903d4f65.tar.gz
refactor gv_add_by_type
gv_add_by_type was added in commit d5713896ec in 5.11.0 . Improve gv_add_by_type by making it return the newly created SV*, instead of the the GV *, which the caller must deref both the GV head to get svu and then deref a slice into the GP, even though it already derefed svu and GP right before, to figure out whether to call gv_add_by_type in the first place. The original version of this patch had gv_add_by_type returning a SV ** to ensure lvalue-ness but it was discovered it wasn't needed and not smart. -rename gv_add_by_type since it was removed from public api and its proto changed -remove null check since it is impossible to pass null through GvAVn(), and unlikely with gv_AVadd, null segvs reliably crash in the rare case of a problem -instead of S_gv_init_svtype and gv_add_by_type using a tree of logic/ conditional jumps in asm, use a lookup table, GPe (e=enum or entry) enums are identical to offsets into the GP struct, all of then fit under 0xFF, if the CC and CPU arch wants, CC can load the const once into a register, then use the number for the 2nd deref, then use the number again as an arg to gv_add_by_type, the low (&~0xf) or high (<<2) 2 bits in a GPe can be used for something else in the future since GPe is pointer aligned -SVt_LAST triggers "panic: sv_upgrade to unknown type", so use that value for entries of a GP which are not SV head *s and are invalid to pass as an arg -remove the tree of logic in S_gv_init_svtype, replace with a table -S_gv_init_svtype is now tail call friendly and very small -change the GV**n to be rvalues only, assigning to GV**n is probably a memory leak -fix 1 core GV**n as lvalue use -GvSVn's unusual former definition is from commit 547f15c3f9 in 2005 and DEFSV as lvalue is gone in core as of commit 414bf5ae08 from 2008 since all the GV**n macros are now rvalues, this goes too -PTRPTR2IDX and PTRSIZELOG2 could use better names -in pp_rv2av dont declare strings like that VC linker won't dedup that, and other parts of core also have "an ARRAY", perl521.dll previously had 2 "an ARRAY" and "a HASH" strings in it due to this before VC 2003 32 perl521.dll .text 0xc8813 in machine code bytes after .text 0xc8623
Diffstat (limited to 'gv.h')
-rw-r--r--gv.h31
1 files changed, 21 insertions, 10 deletions
diff --git a/gv.h b/gv.h
index 1d5915433d..77920176e5 100644
--- a/gv.h
+++ b/gv.h
@@ -101,9 +101,9 @@ Return the CV from the GV.
#define GvSV(gv) (GvGP(gv)->gp_sv)
#ifdef PERL_DONT_CREATE_GVSV
-#define GvSVn(gv) (*(GvGP(gv)->gp_sv ? \
- &(GvGP(gv)->gp_sv) : \
- &(GvGP(gv_SVadd(gv))->gp_sv)))
+#define GvSVn(gv) (GvGP(gv)->gp_sv ? \
+ GvGP(gv)->gp_sv : \
+ Perl_gv_add_by_type_p(aTHX_ (gv), GPe_SV))
#else
#define GvSVn(gv) GvSV(gv)
#endif
@@ -121,19 +121,22 @@ Return the CV from the GV.
: NULL \
)
#define GvIOp(gv) (GvGP(gv)->gp_io)
-#define GvIOn(gv) (GvIO(gv) ? GvIOp(gv) : GvIOp(gv_IOadd(gv)))
+#define GvIOn(gv) \
+ (GvIO(gv) \
+ ? GvIOp(gv) \
+ : (struct io *)Perl_gv_add_by_type_p(aTHX_ (gv), GPe_IO))
#define GvFORM(gv) (GvGP(gv)->gp_form)
#define GvAV(gv) (GvGP(gv)->gp_av)
#define GvAVn(gv) (GvGP(gv)->gp_av ? \
GvGP(gv)->gp_av : \
- GvGP(gv_AVadd(gv))->gp_av)
+ (AV*)Perl_gv_add_by_type_p(aTHX_ (gv), GPe_AV))
#define GvHV(gv) ((GvGP(gv))->gp_hv)
#define GvHVn(gv) (GvGP(gv)->gp_hv ? \
GvGP(gv)->gp_hv : \
- GvGP(gv_HVadd(gv))->gp_hv)
+ (HV*)Perl_gv_add_by_type_p(aTHX_ (gv), GPe_HV))
#define GvCV(gv) (0+GvGP(gv)->gp_cv)
#define GvCV_set(gv,cv) (GvGP(gv)->gp_cv = (cv))
@@ -283,10 +286,18 @@ Return the CV from the GV.
: mro_method_changed_in(GvSTASH(gv)) \
)
-#define gv_AVadd(gv) gv_add_by_type((gv), SVt_PVAV)
-#define gv_HVadd(gv) gv_add_by_type((gv), SVt_PVHV)
-#define gv_IOadd(gv) gv_add_by_type((gv), SVt_PVIO)
-#define gv_SVadd(gv) gv_add_by_type((gv), SVt_NULL)
+/* used by Perl_gv_add_by_type_p for option checking, low bits are free here*/
+typedef enum {
+ GPe_SV = STRUCT_OFFSET(GP, gp_sv),
+ GPe_IO = STRUCT_OFFSET(GP, gp_io),
+ GPe_HV = STRUCT_OFFSET(GP, gp_hv),
+ GPe_AV = STRUCT_OFFSET(GP, gp_av),
+} gv_add_type;
+
+#define gv_AVadd(gv) (Perl_gv_add_by_type_p(aTHX_ (gv), GPe_AV), gv)
+#define gv_HVadd(gv) (Perl_gv_add_by_type_p(aTHX_ (gv), GPe_HV), gv)
+#define gv_IOadd(gv) (Perl_gv_add_by_type_p(aTHX_ (gv), GPe_IO), gv)
+#define gv_SVadd(gv) (Perl_gv_add_by_type_p(aTHX_ (gv), GPe_SV), gv)
/*
* Local variables: