diff options
author | David Mitchell <davem@iabyn.com> | 2014-02-28 19:46:15 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-02-28 19:46:15 +0000 |
commit | f5572cf8315f7c5228c30330db88dd3f604cfdc1 (patch) | |
tree | d0538941c0f01aae6d885e49b66ae72db4759520 /scope.c | |
parent | b838857b5256d738820be79973535c28fc4da01c (diff) | |
parent | 9af159903dbf2799f16d8b83e8e556583aabd3e2 (diff) | |
download | perl-f5572cf8315f7c5228c30330db88dd3f604cfdc1.tar.gz |
[MERGE] tweak in-place branch of SAVEt_CLEARSV
clean up the code that clears lexical vars on scope exit; chiefly, wrap
all the individual 'unusual case' flag tests in a single big test of the
union of all such flags, so that simple lexical vars skip all the tests.
Diffstat (limited to 'scope.c')
-rw-r--r-- | scope.c | 60 |
1 files changed, 40 insertions, 20 deletions
@@ -1036,28 +1036,46 @@ Perl_leave_scope(pTHX_ I32 base) (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) ? "clear" : "abandon" )); + assert(SvPADMY(sv)); + /* Can clear pad variable in place? */ - if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) { - /* - * if a my variable that was made readonly is going out of - * scope, we want to remove the readonlyness so that it can - * go out of scope quietly - */ - if (SvPADMY(sv) && !SvFAKE(sv)) - SvREADONLY_off(sv); - - if (SvTYPE(sv) == SVt_PVHV) - Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv)); - if (SvMAGICAL(sv)) + if (SvREFCNT(sv) == 1 && !SvOBJECT(sv)) { + + /* these flags are the union of all the relevant flags + * in the individual conditions within */ + if (UNLIKELY(SvFLAGS(sv) & ( + SVf_READONLY /* for SvREADONLY_off() */ + | (SVs_GMG|SVs_SMG|SVs_RMG) /* SvMAGICAL() */ + | SVf_OOK + | SVf_THINKFIRST))) { - sv_unmagic(sv, PERL_MAGIC_backref); - if (SvTYPE(sv) != SVt_PVCV) - mg_free(sv); - } - if (SvTHINKFIRST(sv)) - sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF - |SV_COW_DROP_PV); + /* if a my variable that was made readonly is + * going out of scope, we want to remove the + * readonlyness so that it can go out of scope + * quietly + */ + if (SvREADONLY(sv) && !SvFAKE(sv)) + SvREADONLY_off(sv); + + if (SvOOK(sv)) { /* OOK or HvAUX */ + if (SvTYPE(sv) == SVt_PVHV) + Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv)); + else + sv_backoff(sv); + } + + if (SvMAGICAL(sv)) { + /* note that backrefs (either in HvAUX or magic) + * must be removed before other magic */ + sv_unmagic(sv, PERL_MAGIC_backref); + if (SvTYPE(sv) != SVt_PVCV) + mg_free(sv); + } + if (SvTHINKFIRST(sv)) + sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF + |SV_COW_DROP_PV); + } switch (SvTYPE(sv)) { case SVt_NULL: break; @@ -1077,7 +1095,9 @@ Perl_leave_scope(pTHX_ I32 base) break; } default: - SvOK_off(sv); + assert_not_ROK(sv); + assert_not_glob(sv); + SvFLAGS(sv) &=~ (SVf_OK|SVf_IVisUV|SVf_UTF8); break; } SvPADSTALE_on(sv); /* mark as no longer live */ |