diff options
author | David Mitchell <davem@iabyn.com> | 2010-07-12 20:53:04 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2010-07-14 23:06:18 +0100 |
commit | 803f274831f937654d48f8cf0468521cbf8f5dff (patch) | |
tree | 297f701cf0a8ef3af29be3017402207f1fa62707 /embed.h | |
parent | 96bafef935f82644670a19c8ca57886c240cd969 (diff) | |
download | perl-803f274831f937654d48f8cf0468521cbf8f5dff.tar.gz |
protect CvGV weakref with backref
Each CV usually has a pointer, CvGV(cv), back to the GV that corresponds
to the CV's name (or to *foo::__ANON__ for anon CVs). This pointer wasn't
reference counted, to avoid loops. This could leave it dangling if the GV
is deleted.
We fix this by:
For named subs, adding backref magic to the GV, so that when the GV is
freed, it can trigger processing the CV's CvGV field. This processing
consists of: if it looks like the freeing of the GV is about to trigger
freeing of the CV too, set it to NULL; otherwise make it point to
*foo::__ANON__ (and set CvAONON(cv)).
For anon subs, make CvGV a strong reference, i.e. increment the refcnt of
*foo::__ANON__. This doesn't cause a loop, since in this case the
__ANON__ glob doesn't point to the CV. This also avoids dangling pointers
if someone does an explicit 'delete $foo::{__ANON__}'.
Note that there was already some partial protection for CvGV with
commit f1c32fec87699aee2eeb638f44135f21217d2127. This worked by
anonymising any corresponding CV when freeing a stash or stash entry.
This had two drawbacks. First it didn't fix CVs that were anonmous or that
weren't currently pointed to by the GV (e.g. after local *foo), and
second, it caused *all* CVs to get anonymised during cleanup, even the
ones that would have been deleted shortly afterwards anyway. This commit
effectively removes that former commit, while reusing a bit of the
actual anonymising code.
Diffstat (limited to 'embed.h')
-rw-r--r-- | embed.h | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -292,6 +292,9 @@ #define gv_fetchpv Perl_gv_fetchpv #define gv_fullname Perl_gv_fullname #define gv_fullname4 Perl_gv_fullname4 +#ifdef PERL_CORE +#define cvgv_set Perl_cvgv_set +#endif #define gv_init Perl_gv_init #define gv_name_set Perl_gv_name_set #ifdef PERL_CORE @@ -1243,7 +1246,6 @@ #ifdef PERL_CORE #define hsplit S_hsplit #define hfreeentries S_hfreeentries -#define anonymise_cv S_anonymise_cv #define new_he S_new_he #define save_hek_flags S_save_hek_flags #define hv_magic_check S_hv_magic_check @@ -1614,6 +1616,7 @@ #define glob_assign_glob S_glob_assign_glob #define glob_assign_ref S_glob_assign_ref #define ptr_table_find S_ptr_table_find +#define anonymise_cv_maybe S_anonymise_cv_maybe #endif #endif #if defined(PERL_IN_TOKE_C) @@ -2729,6 +2732,7 @@ #define gv_fullname(a,b) Perl_gv_fullname(aTHX_ a,b) #define gv_fullname4(a,b,c,d) Perl_gv_fullname4(aTHX_ a,b,c,d) #ifdef PERL_CORE +#define cvgv_set(a,b) Perl_cvgv_set(aTHX_ a,b) #endif #define gv_init(a,b,c,d,e) Perl_gv_init(aTHX_ a,b,c,d,e) #define gv_name_set(a,b,c,d) Perl_gv_name_set(aTHX_ a,b,c,d) @@ -3682,7 +3686,6 @@ #ifdef PERL_CORE #define hsplit(a) S_hsplit(aTHX_ a) #define hfreeentries(a) S_hfreeentries(aTHX_ a) -#define anonymise_cv(a,b) S_anonymise_cv(aTHX_ a,b) #define new_he() S_new_he(aTHX) #define save_hek_flags S_save_hek_flags #define hv_magic_check S_hv_magic_check @@ -4066,6 +4069,7 @@ #define glob_assign_glob(a,b,c) S_glob_assign_glob(aTHX_ a,b,c) #define glob_assign_ref(a,b) S_glob_assign_ref(aTHX_ a,b) #define ptr_table_find S_ptr_table_find +#define anonymise_cv_maybe(a,b) S_anonymise_cv_maybe(aTHX_ a,b) #endif #endif #if defined(PERL_IN_TOKE_C) |