X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/e3b8966e2a0e0357b86674327ee528dbb5f122a6..d7bdb612ac7ecb7adfb85cf8f7484e81501984a7:/cv.h diff --git a/cv.h b/cv.h index c7c7a73..6fdf5cb 100644 --- a/cv.h +++ b/cv.h @@ -1,67 +1,86 @@ /* cv.h * - * Copyright (c) 1991-1997, Larry Wall + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, + * 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ -/* This structure much match the beginning of XPVFM */ +/* This structure must the beginning of XPVFM in sv.h */ struct xpvcv { - char * xpv_pv; /* pointer to malloced string */ - STRLEN xpv_cur; /* length of xp_pv as a C string */ - STRLEN xpv_len; /* allocated size */ - IV xof_off; /* integer value */ - double xnv_nv; /* numeric value, if any */ - MAGIC* xmg_magic; /* magic for scalar array */ - HV* xmg_stash; /* class package */ - - HV * xcv_stash; - OP * xcv_start; - OP * xcv_root; - void (*xcv_xsub) _((CV* _CPERLproto)); - ANY xcv_xsubany; - GV * xcv_gv; - GV * xcv_filegv; - long xcv_depth; /* >= 2 indicates recursive call */ - AV * xcv_padlist; - CV * xcv_outside; -#ifdef USE_THREADS - perl_mutex *xcv_mutexp; - struct perl_thread *xcv_owner; /* current owner thread */ -#endif /* USE_THREADS */ - cv_flags_t xcv_flags; + _XPV_HEAD; + _XPVCV_COMMON; + I32 xcv_depth; /* >= 2 indicates recursive call */ }; -#define Nullcv Null(CV*) - -#define CvSTASH(sv) ((XPVCV*)SvANY(sv))->xcv_stash -#define CvSTART(sv) ((XPVCV*)SvANY(sv))->xcv_start -#define CvROOT(sv) ((XPVCV*)SvANY(sv))->xcv_root -#define CvXSUB(sv) ((XPVCV*)SvANY(sv))->xcv_xsub -#define CvXSUBANY(sv) ((XPVCV*)SvANY(sv))->xcv_xsubany -#define CvGV(sv) ((XPVCV*)SvANY(sv))->xcv_gv -#define CvFILEGV(sv) ((XPVCV*)SvANY(sv))->xcv_filegv -#define CvDEPTH(sv) ((XPVCV*)SvANY(sv))->xcv_depth -#define CvPADLIST(sv) ((XPVCV*)SvANY(sv))->xcv_padlist -#define CvOUTSIDE(sv) ((XPVCV*)SvANY(sv))->xcv_outside -#ifdef USE_THREADS -#define CvMUTEXP(sv) ((XPVCV*)SvANY(sv))->xcv_mutexp -#define CvOWNER(sv) ((XPVCV*)SvANY(sv))->xcv_owner -#endif /* USE_THREADS */ -#define CvFLAGS(sv) ((XPVCV*)SvANY(sv))->xcv_flags - -#define CVf_CLONE 0x0001 /* anon CV uses external lexicals */ -#define CVf_CLONED 0x0002 /* a clone of one of those */ -#define CVf_ANON 0x0004 /* CvGV() can't be trusted */ -#define CVf_OLDSTYLE 0x0008 -#define CVf_UNIQUE 0x0010 /* can't be cloned */ -#define CVf_NODEBUG 0x0020 /* no DB::sub indirection for this CV +/* +=head1 Handy Values + +=for apidoc AmU||Nullcv +Null CV pointer. + +(deprecated - use C<(CV *)NULL> instead) + +=head1 CV Manipulation Functions + +=for apidoc Am|HV*|CvSTASH|CV* cv +Returns the stash of the CV. + +=cut +*/ + +#ifndef PERL_CORE +# define Nullcv Null(CV*) +#endif + +#define CvSTASH(sv) (0+((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_stash) +#define CvSTASH_set(cv,st) Perl_cvstash_set(aTHX_ cv, st) +#define CvSTART(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_start_u.xcv_start +#define CvROOT(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_root_u.xcv_root +#define CvXSUB(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_root_u.xcv_xsub +#define CvXSUBANY(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_start_u.xcv_xsubany +#define CvGV(sv) (0+((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_gv) +#define CvGV_set(cv,gv) Perl_cvgv_set(aTHX_ cv, gv) +#define CvFILE(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_file +#ifdef USE_ITHREADS +# define CvFILE_set_from_cop(sv, cop) (CvFILE(sv) = savepv(CopFILE(cop))) +#else +# define CvFILE_set_from_cop(sv, cop) (CvFILE(sv) = CopFILE(cop)) +#endif +#define CvFILEGV(sv) (gv_fetchfile(CvFILE(sv))) +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define CvDEPTH(sv) (*({const CV *const _cvdepth = (const CV *)sv; \ + assert(SvTYPE(_cvdepth) == SVt_PVCV); \ + &((XPVCV*)SvANY(_cvdepth))->xcv_depth; \ + })) +#else +# define CvDEPTH(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_depth +#endif +#define CvPADLIST(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_padlist +#define CvOUTSIDE(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_outside +#define CvFLAGS(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_flags +#define CvOUTSIDE_SEQ(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_outside_seq + +#define CVf_METHOD 0x0001 /* CV is explicitly marked as a method */ +#define CVf_LVALUE 0x0002 /* CV return value can be used as lvalue */ +#define CVf_CONST 0x0004 /* inlinable sub */ +#define CVf_ISXSUB 0x0008 /* CV is an XSUB, not pure perl. */ + +#define CVf_WEAKOUTSIDE 0x0010 /* CvOUTSIDE isn't ref counted */ +#define CVf_CLONE 0x0020 /* anon CV uses external lexicals */ +#define CVf_CLONED 0x0040 /* a clone of one of those */ +#define CVf_ANON 0x0080 /* CV is not pointed to by a GV */ +#define CVf_UNIQUE 0x0100 /* sub is only called once (eg PL_main_cv, + * require, eval). */ +#define CVf_NODEBUG 0x0200 /* no DB::sub indirection for this CV (esp. useful for special XSUBs) */ -#define CVf_METHOD 0x0040 /* CV is explicitly marked as a method */ -#define CVf_LOCKED 0x0080 /* CV locks itself or first arg on entry */ +#define CVf_CVGV_RC 0x0400 /* CvGV is reference counted */ + +/* This symbol for optimised communication between toke.c and op.c: */ +#define CVf_BUILTIN_ATTRS (CVf_METHOD|CVf_LVALUE) #define CvCLONE(cv) (CvFLAGS(cv) & CVf_CLONE) #define CvCLONE_on(cv) (CvFLAGS(cv) |= CVf_CLONE) @@ -75,10 +94,6 @@ struct xpvcv { #define CvANON_on(cv) (CvFLAGS(cv) |= CVf_ANON) #define CvANON_off(cv) (CvFLAGS(cv) &= ~CVf_ANON) -#define CvOLDSTYLE(cv) (CvFLAGS(cv) & CVf_OLDSTYLE) -#define CvOLDSTYLE_on(cv) (CvFLAGS(cv) |= CVf_OLDSTYLE) -#define CvOLDSTYLE_off(cv) (CvFLAGS(cv) &= ~CVf_OLDSTYLE) - #define CvUNIQUE(cv) (CvFLAGS(cv) & CVf_UNIQUE) #define CvUNIQUE_on(cv) (CvFLAGS(cv) |= CVf_UNIQUE) #define CvUNIQUE_off(cv) (CvFLAGS(cv) &= ~CVf_UNIQUE) @@ -91,6 +106,101 @@ struct xpvcv { #define CvMETHOD_on(cv) (CvFLAGS(cv) |= CVf_METHOD) #define CvMETHOD_off(cv) (CvFLAGS(cv) &= ~CVf_METHOD) -#define CvLOCKED(cv) (CvFLAGS(cv) & CVf_LOCKED) -#define CvLOCKED_on(cv) (CvFLAGS(cv) |= CVf_LOCKED) -#define CvLOCKED_off(cv) (CvFLAGS(cv) &= ~CVf_LOCKED) +#define CvLVALUE(cv) (CvFLAGS(cv) & CVf_LVALUE) +#define CvLVALUE_on(cv) (CvFLAGS(cv) |= CVf_LVALUE) +#define CvLVALUE_off(cv) (CvFLAGS(cv) &= ~CVf_LVALUE) + +#define CvEVAL(cv) (CvUNIQUE(cv) && !SvFAKE(cv)) +#define CvEVAL_on(cv) (CvUNIQUE_on(cv),SvFAKE_off(cv)) +#define CvEVAL_off(cv) CvUNIQUE_off(cv) + +/* BEGIN|CHECK|INIT|UNITCHECK|END */ +#define CvSPECIAL(cv) (CvUNIQUE(cv) && SvFAKE(cv)) +#define CvSPECIAL_on(cv) (CvUNIQUE_on(cv),SvFAKE_on(cv)) +#define CvSPECIAL_off(cv) (CvUNIQUE_off(cv),SvFAKE_off(cv)) + +#define CvCONST(cv) (CvFLAGS(cv) & CVf_CONST) +#define CvCONST_on(cv) (CvFLAGS(cv) |= CVf_CONST) +#define CvCONST_off(cv) (CvFLAGS(cv) &= ~CVf_CONST) + +#define CvWEAKOUTSIDE(cv) (CvFLAGS(cv) & CVf_WEAKOUTSIDE) +#define CvWEAKOUTSIDE_on(cv) (CvFLAGS(cv) |= CVf_WEAKOUTSIDE) +#define CvWEAKOUTSIDE_off(cv) (CvFLAGS(cv) &= ~CVf_WEAKOUTSIDE) + +#define CvISXSUB(cv) (CvFLAGS(cv) & CVf_ISXSUB) +#define CvISXSUB_on(cv) (CvFLAGS(cv) |= CVf_ISXSUB) +#define CvISXSUB_off(cv) (CvFLAGS(cv) &= ~CVf_ISXSUB) + +#define CvCVGV_RC(cv) (CvFLAGS(cv) & CVf_CVGV_RC) +#define CvCVGV_RC_on(cv) (CvFLAGS(cv) |= CVf_CVGV_RC) +#define CvCVGV_RC_off(cv) (CvFLAGS(cv) &= ~CVf_CVGV_RC) + +/* Flags for newXS_flags */ +#define XS_DYNAMIC_FILENAME 0x01 /* The filename isn't static */ + +/* +=head1 CV reference counts and CvOUTSIDE + +=for apidoc m|bool|CvWEAKOUTSIDE|CV *cv + +Each CV has a pointer, C, to its lexically enclosing +CV (if any). Because pointers to anonymous sub prototypes are +stored in C<&> 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 C in the I that the parent +has a C<&> pad slot pointing back to us. In this case, we set the +C 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, eg + + 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 +C 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 C causes the chain of Cs to be followed, +and the freed BEGIN is accessed. + +To avoid this, whenever a CV and its associated pad is freed, any +C<&> 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 C 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 C<$a> above). + +One other thing to consider is that a CV may be merely undefined +rather than freed, eg C. In this case, its refcount may +not have reached zero, but we still delete its pad and its C etc. +Since various children may still have their C pointing at this +undefined CV, we keep its own C 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; + print $a->(); + +=cut +*/ + +typedef OP *(*Perl_call_checker)(pTHX_ OP *, GV *, SV *); + +/* + * Local variables: + * c-indentation-style: bsd + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * + * ex: set ts=8 sts=4 sw=4 noet: + */