summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorVincent Pit <perl@profvince.com>2011-06-25 14:25:25 +0200
committerVincent Pit <perl@profvince.com>2011-06-26 00:07:29 +0200
commit2b9a64577b41d2e4715e02f855894f80e1e293e8 (patch)
tree995f9e224ed75facc0498ff09966bf1724b0cc1d /pp_ctl.c
parentb9d76716561152289be3c4e24746173674d3b33a (diff)
downloadperl-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.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index bde43998d4..f20c196d9a 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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;