In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/c349b9a040f3048e07809d40d2a1c12e8873b4ca?hp=aea0412a260d9d7295c0a5bebb8bb6978dc02ccd>
- Log ----------------------------------------------------------------- commit c349b9a040f3048e07809d40d2a1c12e8873b4ca Author: David Mitchell <[email protected]> Date: Wed Mar 30 15:11:26 2016 +0100 Improve code comments for some ctx stuff * in pp_return(), some comments were out of date about how leave_adjust_stacks() is called ; * add a comment to all the functions that pp_return() tail-calls to the effect that they can be tail-called; * make it clearer when/why OPf_SPECIAL is set on OP_LEAVE; * CXt_LOOP_PLAIN can be a while loop as well as a plain block. ----------------------------------------------------------------------- Summary of changes: cop.h | 12 ++++++------ op.h | 3 ++- pp_ctl.c | 29 ++++++++++++++++++----------- pp_hot.c | 2 ++ 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/cop.h b/cop.h index 1795dc3..da29572 100644 --- a/cop.h +++ b/cop.h @@ -847,12 +847,12 @@ struct context { /* be careful of the ordering of these five. Macros like CxTYPE_is_LOOP, * CxFOREACH compare ranges */ -#define CXt_LOOP_ARY 4 /* for (@ary) {} */ -#define CXt_LOOP_LAZYSV 5 /* for ('a'..'z') {} */ -#define CXt_LOOP_LAZYIV 6 /* for (1..9) {} */ -#define CXt_LOOP_LIST 7 /* for (1,2,3) {} */ -#define CXt_LOOP_PLAIN 8 /* {} */ - +#define CXt_LOOP_ARY 4 /* for (@ary) { ...; } */ +#define CXt_LOOP_LAZYSV 5 /* for ('a'..'z') { ...; } */ +#define CXt_LOOP_LAZYIV 6 /* for (1..9) { ...; } */ +#define CXt_LOOP_LIST 7 /* for (1,2,3) { ...; } */ +#define CXt_LOOP_PLAIN 8 /* while (...) { ...; } + or plain block { ...; } */ #define CXt_SUB 9 #define CXt_FORMAT 10 #define CXt_EVAL 11 diff --git a/op.h b/op.h index 00d9a4c..3ded4bb 100644 --- a/op.h +++ b/op.h @@ -113,7 +113,8 @@ Deprecated. Use C<GIMME_V> instead. /* On local LVAL, don't init local value. */ /* On OP_SORT, subroutine is inlined. */ /* On OP_NOT, inversion was implicit. */ - /* On OP_LEAVE, don't restore curpm. */ + /* On OP_LEAVE, don't restore curpm, e.g. + * /(...)/ while ...>; */ /* On truncate, we truncate filehandle */ /* On control verbs, we saw no label */ /* On flipflop, we saw ... instead of .. */ diff --git a/pp_ctl.c b/pp_ctl.c index 7b31bbb..99ff59a 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -2052,7 +2052,8 @@ PP(pp_leave) assert(CxTYPE(cx) == CXt_BLOCK); if (PL_op->op_flags & OPf_SPECIAL) - cx->blk_oldpm = PL_curpm; /* fake block should preserve $1 et al */ + /* fake block should preserve $1 et al; e.g. /(...)/ while ...; */ + cx->blk_oldpm = PL_curpm; oldsp = PL_stack_base + cx->blk_oldsp; gimme = cx->blk_gimme; @@ -2256,6 +2257,8 @@ PP(pp_leaveloop) * * Any changes made to this function may need to be copied to pp_leavesub * and vice-versa. + * + * also tail-called by pp_return */ PP(pp_leavesublv) @@ -2397,20 +2400,18 @@ PP(pp_return) } /* There are contexts that need popping. Doing this may free the - * return value(s), so preserve them first, e.g. popping the plain + * return value(s), so preserve them first: e.g. popping the plain * loop here would free $x: * sub f { { my $x = 1; return $x } } * We may also need to shift the args down; for example, * for (1,2) { return 3,4 } - * leaves 1,2,3,4 on the stack. Both these actions can be done by - * leave_adjust_stacks(). By calling it with and lvalue "pass - * all" action, we just bump the ref count and mortalise the args - * that need it, do a FREETMPS. The "scan the args and maybe copy - * them" process will be repeated by whoever we tail-call (e.g. - * pp_leaveeval), where any copying etc will be done. That is to - * say, in this code path two scans of the args will be done; the - * first just shifts and preserves; the second is the "real" arg - * processing, based on the type of return. + * leaves 1,2,3,4 on the stack. Both these actions will be done by + * leave_adjust_stacks(), along with freeing any temps. Note that + * whoever we tail-call (e.g. pp_leaveeval) will also call + * leave_adjust_stacks(); however, the second call is likely to + * just see a bunch of SvTEMPs with a ref count of 1, and so just + * pass them through, rather than copying them again. So this + * isn't as inefficient as it sounds. */ cx = &cxstack[cxix]; PUTBACK; @@ -4201,6 +4202,9 @@ PP(pp_entereval) } } + +/* also tail-called by pp_return */ + PP(pp_leaveeval) { SV **oldsp; @@ -4307,6 +4311,9 @@ PP(pp_entertry) return DOCATCH(PL_op->op_next); } + +/* also tail-called by pp_return */ + PP(pp_leavetry) { SV **oldsp; diff --git a/pp_hot.c b/pp_hot.c index d7fa3d2..d6cb1aa 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -3623,6 +3623,8 @@ Perl_leave_adjust_stacks(pTHX_ SV **from_sp, SV **to_sp, U8 gimme, int pass) } +/* also tail-called by pp_return */ + PP(pp_leavesub) { U8 gimme; -- Perl5 Master Repository
