diff options
author | Vincent Pit <perl@profvince.com> | 2011-06-25 14:25:25 +0200 |
---|---|---|
committer | Vincent Pit <perl@profvince.com> | 2011-06-26 00:07:29 +0200 |
commit | 2b9a64577b41d2e4715e02f855894f80e1e293e8 (patch) | |
tree | 995f9e224ed75facc0498ff09966bf1724b0cc1d /pp_ctl.c | |
parent | b9d76716561152289be3c4e24746173674d3b33a (diff) | |
download | perl-2b9a64577b41d2e4715e02f855894f80e1e293e8.tar.gz |
Move pp_enter() and pp_leave() with their friends in pp_ctl.c
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 76 |
1 files changed, 76 insertions, 0 deletions
@@ -2083,6 +2083,82 @@ S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 fla return newsp; } +PP(pp_enter) +{ + dVAR; dSP; + register PERL_CONTEXT *cx; + I32 gimme = OP_GIMME(PL_op, -1); + + if (gimme == -1) { + if (cxstack_ix >= 0) { + /* If this flag is set, we're just inside a return, so we should + * store the caller's context */ + gimme = (PL_op->op_flags & OPf_SPECIAL) + ? block_gimme() + : cxstack[cxstack_ix].blk_gimme; + } else + gimme = G_SCALAR; + } + + ENTER_with_name("block"); + + SAVETMPS; + PUSHBLOCK(cx, CXt_BLOCK, SP); + + RETURN; +} + +PP(pp_leave) +{ + dVAR; dSP; + register PERL_CONTEXT *cx; + SV **newsp; + PMOP *newpm; + I32 gimme; + + if (PL_op->op_flags & OPf_SPECIAL) { + cx = &cxstack[cxstack_ix]; + cx->blk_oldpm = PL_curpm; /* fake block should preserve $1 et al */ + } + + POPBLOCK(cx,newpm); + + gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR); + + TAINT_NOT; + if (gimme == G_VOID) + SP = newsp; + else if (gimme == G_SCALAR) { + register SV **mark; + MARK = newsp + 1; + if (MARK <= SP) { + if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP)) + *MARK = TOPs; + else + *MARK = sv_mortalcopy(TOPs); + } else { + MEXTEND(mark,0); + *MARK = &PL_sv_undef; + } + SP = MARK; + } + else if (gimme == G_ARRAY) { + /* in case LEAVE wipes old return values */ + register SV **mark; + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) { + *mark = sv_mortalcopy(*mark); + TAINT_NOT; /* Each item is independent */ + } + } + } + PL_curpm = newpm; /* Don't pop $1 et al till now */ + + LEAVE_with_name("block"); + + RETURN; +} + PP(pp_enteriter) { dVAR; dSP; dMARK; |