summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-12-17 12:13:09 +0000
committerDavid Mitchell <davem@iabyn.com>2016-02-03 09:18:34 +0000
commit75bc488d4e88019e591cb7483510cbd02ac47320 (patch)
treefc6aad4b7475ac855c032df98ad58dfbaa0fcf90 /pp_ctl.c
parente02ce34b5a3c7daaf3131c6aea9a98f7dbbba1b5 (diff)
downloadperl-75bc488d4e88019e591cb7483510cbd02ac47320.tar.gz
replace leave_common() with leave_adjust_stacks()
Make the remaining callers of S_leave_common() use leave_adjust_stacks() instead, then delete this static function. This brings the benefits of freeing TEMPS on all scope exists that has already been introduced on sub exits; uses the optimised code for creating mortal copies; and finally unifies all the different 'process return args on scope exit' implementations into single function.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c76
1 files changed, 9 insertions, 67 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 69b24468a2..f5d786e22a 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2024,65 +2024,6 @@ PP(pp_dbstate)
return NORMAL;
}
-/* S_leave_common: Common code that many functions in this file use on
- scope exit.
-
- Process the return args on the stack in the range (mark+1..PL_stack_sp)
- based on context, with any final args starting at newsp+1.
- Args are mortal copied (or mortalied if lvalue) unless its safe to use
- as-is, based on whether it has the specified flags. Note that most
- callers specify flags as (SVs_PADTMP|SVs_TEMP), while leaveeval skips
- SVs_PADTMP since its optree gets immediately freed, freeing its padtmps
- at the same time.
-
- Also, taintedness is cleared.
-*/
-
-STATIC void
-S_leave_common(pTHX_ SV **newsp, SV **mark, I32 gimme,
- U32 flags, bool lvalue)
-{
- dSP;
- PERL_ARGS_ASSERT_LEAVE_COMMON;
-
- TAINT_NOT;
- if (gimme == G_SCALAR) {
- if (MARK < SP) {
- SV *sv = *SP;
-
- *++newsp = ((SvFLAGS(sv) & flags) && SvREFCNT(sv) == 1
- && !SvMAGICAL(sv))
- ? sv
- : lvalue
- ? sv_2mortal(SvREFCNT_inc_simple_NN(sv))
- : sv_mortalcopy(sv);
- }
- else {
- EXTEND(newsp, 1);
- *++newsp = &PL_sv_undef;
- }
- }
- else if (gimme == G_ARRAY) {
- /* in case LEAVE wipes old return values */
- while (++MARK <= SP) {
- SV *sv = *MARK;
- if ((SvFLAGS(sv) & flags) && SvREFCNT(sv) == 1
- && !SvMAGICAL(sv))
- *++newsp = sv;
- else {
- *++newsp = lvalue
- ? sv_2mortal(SvREFCNT_inc_simple_NN(sv))
- : sv_mortalcopy(sv);
- TAINT_NOT; /* Each item is independent */
- }
- }
- /* When this function was called with MARK == newsp, we reach this
- * point with SP == newsp. */
- }
-
- PL_stack_sp = newsp;
-}
-
PP(pp_enter)
{
@@ -2114,8 +2055,8 @@ PP(pp_leave)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP,
- PL_op->op_private & OPpLVALUE);
+ leave_adjust_stacks(newsp, newsp, gimme,
+ PL_op->op_private & OPpLVALUE ? 3 : 1);
CX_LEAVE_SCOPE(cx);
POPBASICBLK(cx);
@@ -2286,8 +2227,8 @@ PP(pp_leaveloop)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, MARK, gimme, SVs_PADTMP|SVs_TEMP,
- PL_op->op_private & OPpLVALUE);
+ leave_adjust_stacks(MARK, newsp, gimme,
+ PL_op->op_private & OPpLVALUE ? 3 : 1);
CX_LEAVE_SCOPE(cx);
POPLOOP(cx); /* Stack values are safe: release loop vars ... */
@@ -4279,7 +4220,7 @@ PP(pp_leaveeval)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 0);
/* the POPEVAL does a leavescope, which frees the optree associated
* with eval, which if it frees the nextstate associated with
@@ -4374,7 +4315,7 @@ PP(pp_leavetry)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 1);
CX_LEAVE_SCOPE(cx);
POPEVAL(cx);
POPBLOCK(cx);
@@ -4417,7 +4358,7 @@ PP(pp_leavegiven)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 1);
CX_LEAVE_SCOPE(cx);
POPGIVEN(cx);
@@ -5003,7 +4944,8 @@ PP(pp_leavewhen)
if (gimme == G_VOID)
PL_stack_sp = newsp;
else
- leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+ leave_adjust_stacks(newsp, newsp, gimme, 1);
+
/* pop the WHEN, BLOCK and anything else before the GIVEN/FOR */
assert(cxix < cxstack_ix);
dounwind(cxix);