clone() wasn't cloning the whole stack
authorDavid Mitchell <davem@iabyn.com>
Fri, 16 Nov 2012 18:04:49 +0000 (18:04 +0000)
committerDavid Mitchell <davem@iabyn.com>
Fri, 16 Nov 2012 19:06:38 +0000 (19:06 +0000)
When cloning stacks (e.g. for fake fork), the stack is cloned
by copying the stack AV pointed to by PL_curstackinfo; but the
AvFILL on that AV may not be up to date, resulting in the top N
items of the stack not being cloned. Fix by saving PL_stack_sp
back into AvFILL(PL_curstack) before cloning

ext/XS-APItest/t/clone-with-stack.t
sv.c

index 943a123..7a0cd29 100644 (file)
@@ -17,7 +17,7 @@ if (not $Config{'useithreads'}) {
     skip_all("clone_with_stack requires threads");
 }
 
-plan(3);
+plan(4);
 
 fresh_perl_is( <<'----', <<'====', undef, "minimal clone_with_stack" );
 use XS::APItest;
@@ -51,3 +51,17 @@ ok
 ====
 
 }
+
+{
+    fresh_perl_is( <<'----', <<'====', undef, "clone stack" );
+use XS::APItest;
+sub f {
+    clone_with_stack();
+    0..4;
+}
+print 'X-', 'Y-', join(':', f()), "-Z\n";
+----
+X-Y-0:1:2:3:4-Z
+====
+
+}
diff --git a/sv.c b/sv.c
index 682ac45..4d7219d 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -13493,6 +13493,11 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
        Newxz(PL_scopestack_name, PL_scopestack_max, const char *);
        Copy(proto_perl->Iscopestack_name, PL_scopestack_name, PL_scopestack_ix, const char *);
 #endif
+        /* reset stack AV to correct length before its duped via
+         * PL_curstackinfo */
+        AvFILLp(proto_perl->Icurstack) =
+                            proto_perl->Istack_sp - proto_perl->Istack_base;
+
        /* NOTE: si_dup() looks at PL_markstack */
        PL_curstackinfo         = si_dup(proto_perl->Icurstackinfo, param);