summaryrefslogtreecommitdiff
path: root/gv.h
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-08-30 09:31:47 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-08-30 12:39:39 -0700
commit23496c6ea4cd9e3c09a9fe1878f55f241bdc17e5 (patch)
tree308baee5cf0e50b4fd4b0170aff3f1be4b9b66f2 /gv.h
parent38552987f01ba3c9fbea08e94b95b439e5ded364 (diff)
downloadperl-23496c6ea4cd9e3c09a9fe1878f55f241bdc17e5.tar.gz
Eliminate is_gv_magical_sv
This resolves perl bug #97978. Many built-in variables, like $], are actually created on the fly when first accessed. Perl likes to pretend that these variables have always existed, so it autovivifies the *] glob even in rvalue context (e.g., defined *{"]"}, close "]"). The list of variables that were autovivified was maintained separ- ately (in is_gv_magical_sv) from the code that actually creates them (gv_fetchpvn_flags). ‘Maintained’ is not actually precise: it *wasn’t* being maintained, and there were new variables that never got added to is_gv_magical_sv and one deleted variable that was never removed. There are only two pieces of code that call is_gv_magical_sv, both in pp.c: S_rv2gv (called by *{} and also the implicit *{} that functions like close() provide) and Perl_softrefxv (called by ${}, @{}, %{}). In both cases, the glob is immediately autovivified if is_gv_magical_sv returns true. So this commit eliminates the extra maintenance burden by extirpat- ing is_gv_magical_sv altogether, and replacing it with a new flag to gv_fetchpvn_flags, GvADDMG, which will autovivify a glob *if* it’s a magical one. It does make defined(*{"frobbly"}) slightly slower, in that it creates a temporary glob and then frees it when it sees nothing magical has been done with it. But this case is rare enough it should not matter. At least I got rid of the bugginess.
Diffstat (limited to 'gv.h')
-rw-r--r--gv.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/gv.h b/gv.h
index a70a9060af..b9d04e6b58 100644
--- a/gv.h
+++ b/gv.h
@@ -213,13 +213,17 @@ Return the SV from the GV.
package (so skip checks for :: and ') */
#define GV_AUTOLOAD 0x100 /* gv_fetchmethod_flags() should AUTOLOAD */
#define GV_CROAK 0x200 /* gv_fetchmethod_flags() should croak */
+#define GV_ADDMG 0x400 /* add if magical */
/* SVf_UTF8 (more accurately the return value from SvUTF8) is also valid
as a flag to gv_fetch_pvn_flags, so ensure it lies outside this range.
*/
-#define GV_NOADD_MASK (SVf_UTF8|GV_NOADD_NOINIT|GV_NOEXPAND|GV_NOTQUAL)
-/* The bit flags that don't cause gv_fetchpv() to add a symbol if not found */
+#define GV_NOADD_MASK \
+ (SVf_UTF8|GV_NOADD_NOINIT|GV_NOEXPAND|GV_NOTQUAL|GV_ADDMG)
+/* The bit flags that don't cause gv_fetchpv() to add a symbol if not
+ found (with the exception GV_ADDMG, which *might* cause the symbol
+ to be added) */
#define gv_fullname3(sv,gv,prefix) gv_fullname4(sv,gv,prefix,TRUE)
#define gv_efullname3(sv,gv,prefix) gv_efullname4(sv,gv,prefix,TRUE)