summaryrefslogtreecommitdiff
path: root/pad.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-11-16 16:05:58 +0000
committerNicholas Clark <nick@ccl4.org>2010-11-16 17:06:35 +0000
commitc4528262e132e4ac14d212c3f48061c1abaff502 (patch)
treed8fd4a4707ea8f640514704f04a87b0022826ae4 /pad.c
parent030e240301776dc41782db59632cc6bea179066e (diff)
downloadperl-c4528262e132e4ac14d212c3f48061c1abaff502.tar.gz
Move Perl_cv_undef() from op.c to pad.c
This will allow the non-API function Perl_pad_undef to be inlined into it.
Diffstat (limited to 'pad.c')
-rw-r--r--pad.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/pad.c b/pad.c
index 52d2db64b2..323efc6a70 100644
--- a/pad.c
+++ b/pad.c
@@ -347,7 +347,73 @@ Perl_pad_undef(pTHX_ CV* cv)
}
+/*
+=head1 Embedding Functions
+
+=for apidoc cv_undef
+
+Clear out all the active components of a CV. This can happen either
+by an explicit C<undef &foo>, or by the reference count going to zero.
+In the former case, we keep the CvOUTSIDE pointer, so that any anonymous
+children can still follow the full lexical scope chain.
+
+=cut
+*/
+
+void
+Perl_cv_undef(pTHX_ CV *cv)
+{
+ dVAR;
+
+ PERL_ARGS_ASSERT_CV_UNDEF;
+
+ DEBUG_X(PerlIO_printf(Perl_debug_log,
+ "CV undef: cv=0x%"UVxf" comppad=0x%"UVxf"\n",
+ PTR2UV(cv), PTR2UV(PL_comppad))
+ );
+#ifdef USE_ITHREADS
+ if (CvFILE(cv) && !CvISXSUB(cv)) {
+ /* for XSUBs CvFILE point directly to static memory; __FILE__ */
+ Safefree(CvFILE(cv));
+ }
+ CvFILE(cv) = NULL;
+#endif
+
+ if (!CvISXSUB(cv) && CvROOT(cv)) {
+ if (SvTYPE(cv) == SVt_PVCV && CvDEPTH(cv))
+ Perl_croak(aTHX_ "Can't undef active subroutine");
+ ENTER;
+
+ PAD_SAVE_SETNULLPAD();
+
+ op_free(CvROOT(cv));
+ CvROOT(cv) = NULL;
+ CvSTART(cv) = NULL;
+ LEAVE;
+ }
+ SvPOK_off(MUTABLE_SV(cv)); /* forget prototype */
+ CvGV_set(cv, NULL);
+
+ pad_undef(cv);
+
+ /* remove CvOUTSIDE unless this is an undef rather than a free */
+ if (!SvREFCNT(cv) && CvOUTSIDE(cv)) {
+ if (!CvWEAKOUTSIDE(cv))
+ SvREFCNT_dec(CvOUTSIDE(cv));
+ CvOUTSIDE(cv) = NULL;
+ }
+ if (CvCONST(cv)) {
+ SvREFCNT_dec(MUTABLE_SV(CvXSUBANY(cv).any_ptr));
+ CvCONST_off(cv);
+ }
+ if (CvISXSUB(cv) && CvXSUB(cv)) {
+ CvXSUB(cv) = NULL;
+ }
+ /* delete all flags except WEAKOUTSIDE and CVGV_RC, which indicate the
+ * ref status of CvOUTSIDE and CvGV */
+ CvFLAGS(cv) &= (CVf_WEAKOUTSIDE|CVf_CVGV_RC);
+}
static PADOFFSET
S_pad_add_name_sv(pTHX_ SV *namesv, const U32 flags, HV *typestash,