op.c: Further simplify ck_sort
authorFather Chrysostomos <sprout@cpan.org>
Sat, 14 Jul 2012 13:41:30 +0000 (06:41 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 15 Jul 2012 00:35:31 +0000 (17:35 -0700)
This code currently chases op_next pointers in the sort block to make
sure there is none that can point outside.  To avoid getting stuck in
loops, it has to check for those explicitly.

Instead of nulling out any op_next pointer that points to the leave
op, we can simply turn the leave into a null op (which we already do)
and have the leave op’s op_next pointer point to nothing.

That produces the same result in the end:  Execution of the sort block
is prevented from running rampant and escaping out of it, but exits
the runloop instead, returning control to pp_sort.

op.c

diff --git a/op.c b/op.c
index aa12ef9..211ffb2 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9177,25 +9177,10 @@ Perl_ck_sort(pTHX_ OP *o)
 
        if (kid->op_type == OP_SCOPE || kid->op_type == OP_LEAVE) {
            LINKLIST(kid);
-           if (kid->op_type == OP_SCOPE) {
-               kid->op_next = 0;
-           }
-           else if (kid->op_type == OP_LEAVE) {
-                   OP *k;
+           if (kid->op_type == OP_LEAVE)
                    op_null(kid);                       /* wipe out leave */
-                   kid->op_next = kid;
-
-                   for (k = kLISTOP->op_first->op_next; k; k = k->op_next) {
-                       if (k->op_next == kid)
-                           k->op_next = 0;
-                       /* don't descend into loops */
-                       else if (k->op_type == OP_ENTERLOOP
-                                || k->op_type == OP_ENTERITER)
-                       {
-                           k = cLOOPx(k)->op_lastop;
-                       }
-                   }
-           }
+           /* Prevent execution from escaping out of the sort block. */
+           kid->op_next = 0;
 
            /* provide scalar context for comparison function/block */
            kid = scalar(firstkid);