(deprecated - use (CV *)NULL
instead)
This also has a special use with XS AUTOLOAD subs. See "Autoloading with XSUBs" in perlguts.
If true, indicates that the CvXSUBANY(cv).any_sv
member contains an SV pointer whose reference count should be decremented when the CV itself is freed. In addition, cv_clone()
will increment the reference count, and sv_dup()
will duplicate the entire pointed-to SV if this flag is set.
Any CV that wraps an XSUB has an ANY
union that the XSUB function is free to use for its own purposes. It may be the case that the code wishes to store an SV in the any_sv
member of this union. By setting this flag, this SV reference will be properly reclaimed or duplicated when the CV itself is.
Helper macro to turn on the CvREFCOUNTED_ANYSV
flag.
Helper macro to turn off the CvREFCOUNTED_ANYSV
flag.
Each CV has a pointer, CvOUTSIDE()
, to its lexically enclosing CV (if any). Because pointers to anonymous sub prototypes are stored in &
pad slots, it is a possible to get a circular reference, with the parent pointing to the child and vice-versa. To avoid the ensuing memory leak, we do not increment the reference count of the CV pointed to by CvOUTSIDE
in the one specific instance that the parent has a &
pad slot pointing back to us. In this case, we set the CvWEAKOUTSIDE
flag in the child. This allows us to determine under what circumstances we should decrement the refcount of the parent when freeing the child.
There is a further complication with non-closure anonymous subs (i.e. those that do not refer to any lexicals outside that sub). In this case, the anonymous prototype is shared rather than being cloned. This has the consequence that the parent may be freed while there are still active children, e.g.,
BEGIN {
$a
=
sub
{
eval
'$x'
} }
In this case, the BEGIN is freed immediately after execution since there are no active references to it: the anon sub prototype has CvWEAKOUTSIDE
set since it's not a closure, and $a points to the same CV, so it doesn't contribute to BEGIN's refcount either. When $a is executed, the eval '$x'
causes the chain of CvOUTSIDE
s to be followed, and the freed BEGIN is accessed.
To avoid this, whenever a CV and its associated pad is freed, any &
entries in the pad are explicitly removed from the pad, and if the refcount of the pointed-to anon sub is still positive, then that child's CvOUTSIDE
is set to point to its grandparent. This will only occur in the single specific case of a non-closure anon prototype having one or more active references (such as $a
above).
One other thing to consider is that a CV may be merely undefined rather than freed, eg undef &foo
. In this case, its refcount may not have reached zero, but we still delete its pad and its CvROOT
etc. Since various children may still have their CvOUTSIDE
pointing at this undefined CV, we keep its own CvOUTSIDE
for the time being, so that the chain of lexical scopes is unbroken. For example, the following should print 123:
my
$x
= 123;
sub
tmp {
sub
{
eval
'$x'
} }
my
$a
= tmp();
undef
&tmp
;
$a
->();