summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2021-10-21 14:16:54 +1100
committerTony Cook <tony@develop-help.com>2021-11-15 11:35:42 +1100
commit9c913148860b0e83e6149d37e86cdb29663ee812 (patch)
tree7f710ef653664ac0a0bb48561554f5a45e8ca8ce /gv.c
parent9bce496f83cb607054f21c015c5f377c24c86bfd (diff)
downloadperl-9c913148860b0e83e6149d37e86cdb29663ee812.tar.gz
Add CopFILEAVn() and use it when cleaning up COP pointers
On threaded builds CopFILEAV() calls gv_fetchfile(), which always created the *{"::_<filenamehere"} glob, so the attempted clean up here could recreate the glob, even if it has already been removed when cleaning up a string eval. To avoid this, add CopFILEAVn() that never creates the glob, nor the AV so that the clean up never adds new objects. This change makes the check for PL_phase unnecessary, but that check is much cheaper than the call for gv_fetchfile_flags() that the macro hides, so retain the check.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/gv.c b/gv.c
index 2b8f2d1783..92f01713bf 100644
--- a/gv.c
+++ b/gv.c
@@ -143,17 +143,23 @@ Perl_gv_fetchfile_flags(pTHX_ const char *const name, const STRLEN namelen,
tmpbuf[0] = '_';
tmpbuf[1] = '<';
memcpy(tmpbuf + 2, name, namelen);
- gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE);
- if (!isGV(gv)) {
- gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
+ GV **gvp = (GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, (flags & GVF_NOADD) ? FALSE : TRUE);
+ if (gvp) {
+ gv = *gvp;
+ if (!isGV(gv)) {
+ gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
#ifdef PERL_DONT_CREATE_GVSV
- GvSV(gv) = newSVpvn(name, namelen);
+ GvSV(gv) = newSVpvn(name, namelen);
#else
- sv_setpvn(GvSV(gv), name, namelen);
+ sv_setpvn(GvSV(gv), name, namelen);
#endif
- }
- if (PERLDB_LINE_OR_SAVESRC && !GvAV(gv))
+ }
+ if (PERLDB_LINE_OR_SAVESRC && !GvAV(gv))
hv_magic(GvHVn(gv), GvAVn(gv), PERL_MAGIC_dbfile);
+ }
+ else {
+ gv = NULL;
+ }
if (tmpbuf != smallbuf)
Safefree(tmpbuf);
return gv;
@@ -682,7 +688,7 @@ Perl_gv_fetchmeth_sv(pTHX_ HV *stash, SV *namesv, I32 level, U32 flags)
/*
=for apidoc gv_fetchmeth_pv
-Exactly like L</gv_fetchmeth_pvn>, but takes a nul-terminated string
+Exactly like L</gv_fetchmeth_pvn>, but takes a nul-terminated string
instead of a string/length pair.
=cut
@@ -1536,7 +1542,7 @@ S_gv_stashpvn_internal(pTHX_ const char *name, U32 namelen, I32 flags)
assert(stash);
if (!HvNAME_get(stash)) {
hv_name_set(stash, name, namelen, flags & SVf_UTF8 ? SVf_UTF8 : 0 );
-
+
/* FIXME: This is a repeat of logic in gv_fetchpvn_flags */
/* If the containing stash has multiple effective
names, see that this one gets them, too. */
@@ -1668,7 +1674,7 @@ S_gv_magicalize_isa(pTHX_ GV *gv)
/* This function grabs name and tries to split a stash and glob
* from its contents. TODO better description, comments
- *
+ *
* If the function returns TRUE and 'name == name_end', then
* 'gv' can be directly returned to the caller of gv_fetchpvn_flags
*/
@@ -1684,7 +1690,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
char smallbuf[64]; /* small buffer to avoid a malloc when possible */
PERL_ARGS_ASSERT_PARSE_GV_STASH_NAME;
-
+
if ( full_len > 2
&& **name == '*'
&& isIDFIRST_lazy_if_safe(*name + 1, name_end, is_utf8))
@@ -1790,7 +1796,7 @@ PERL_STATIC_INLINE bool
S_gv_is_in_main(pTHX_ const char *name, STRLEN len, const U32 is_utf8)
{
PERL_ARGS_ASSERT_GV_IS_IN_MAIN;
-
+
/* If it's an alphanumeric variable */
if ( len && isIDFIRST_lazy_if_safe(name, name + len, is_utf8) ) {
/* Some "normal" variables are always in main::,
@@ -1834,7 +1840,7 @@ S_gv_is_in_main(pTHX_ const char *name, STRLEN len, const U32 is_utf8)
/* *{""}, or a special variable like $@ */
else
return TRUE;
-
+
return FALSE;
}
@@ -1842,7 +1848,7 @@ S_gv_is_in_main(pTHX_ const char *name, STRLEN len, const U32 is_utf8)
/* This function is called if parse_gv_stash_name() failed to
* find a stash, or if GV_NOTQUAL or an empty name was passed
* to gv_fetchpvn_flags.
- *
+ *
* It returns FALSE if the default stash can't be found nor created,
* which might happen during global destruction.
*/
@@ -1852,7 +1858,7 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len,
const svtype sv_type)
{
PERL_ARGS_ASSERT_FIND_DEFAULT_STASH;
-
+
/* No stash in name, so see how we can default */
if ( gv_is_in_main(name, len, is_utf8) ) {
@@ -1951,7 +1957,7 @@ S_find_default_stash(pTHX_ HV **stash, const char *name, STRLEN len,
* magicalization, which some variables require need in order
* to work (like %+, %-, %!), so callers must take care of
* that.
- *
+ *
* It returns true if the gv did turn out to be magical one; i.e.,
* if gv_magicalize actually did something.
*/
@@ -1962,7 +1968,7 @@ S_gv_magicalize(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len,
SSize_t paren;
PERL_ARGS_ASSERT_GV_MAGICALIZE;
-
+
if (stash != PL_defstash) { /* not the main stash */
/* We only have to check for a few names here: a, b, EXPORT, ISA
and VERSION. All the others apply only to the main stash or to
@@ -2506,7 +2512,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
if (!stash && !find_default_stash(&stash, name, len, is_utf8, add, sv_type)) {
return NULL;
}
-
+
/* By this point we should have a stash and a name */
gvp = (GV**)hv_fetch(stash,name,is_utf8 ? -(I32)len : (I32)len,add);
if (!gvp || *gvp == (const GV *)&PL_sv_undef) {
@@ -2588,7 +2594,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
if (addmg) {
/* gv_magicalize magicalised this gv, so we want it
* stored in the symtab.
- * Effectively the caller is asking, ‘Does this gv exist?’
+ * Effectively the caller is asking, ‘Does this gv exist?’
* And we respond, ‘Er, *now* it does!’
*/
(void)hv_store(stash,name,len,(SV *)gv,0);
@@ -2599,7 +2605,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
SvREFCNT_dec_NN(gv);
gv = NULL;
}
-
+
if (gv) gv_init_svtype(gv, faking_it ? SVt_PVCV : sv_type);
return gv;
}
@@ -3314,7 +3320,7 @@ Perl_amagic_deref_call(pTHX_ SV *ref, int method) {
return ref;
while ((tmpsv = amagic_call(ref, &PL_sv_undef, method,
- AMGf_noright | AMGf_unary))) {
+ AMGf_noright | AMGf_unary))) {
if (!SvROK(tmpsv))
Perl_croak(aTHX_ "Overloaded dereference did not return a reference");
if (tmpsv == ref || SvRV(tmpsv) == SvRV(ref)) {
@@ -3717,7 +3723,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
if (SvREFCNT(tmpRef) > 1 && (rv_copy = AMG_CALLunary(left,copy_amg))) {
SvRV_set(left, rv_copy);
SvSETMAGIC(left);
- SvREFCNT_dec_NN(tmpRef);
+ SvREFCNT_dec_NN(tmpRef);
}
}