This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Don’t clone closures in rv2cv
authorFather Chrysostomos <sprout@cpan.org>
Thu, 24 May 2012 05:44:25 +0000 (22:44 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 30 May 2012 06:55:21 +0000 (23:55 -0700)
Commit 07055b4c536 (Support named closures) added code to make refer-
encing a closure prototype clone the prototype.  Commit 28757baaaeaa
(inseparable changes from patch from perl5.003_19 to perl5.003_20),
which includes ‘Subject: Rescind named closures’ in its log, appar-
ently did not rescind ‘named closures’ completely, leaving a line of
code that was completetly unused and untested, until just now when I
tried doing something bizarre to see whether some other piece of code
was buggy.  This wasn’t what I expected. :-)

$ ./perl -Ilib -e 'sub MODIFY_CODE_ATTRIBUTES{\&{$_[1]};} my $x; +sub :bar{$x}'
Assertion failed: (depth || SvTYPE(proto) == SVt_PVFM), function Perl_cv_clone, file pad.c, line 1890.
Abort trap

pp.c
t/op/attrs.t

diff --git a/pp.c b/pp.c
index 5107c27..8b61570 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -413,10 +413,7 @@ PP(pp_rv2cv)
     /* (But not in defined().) */
 
     CV *cv = sv_2cv(TOPs, &stash_unused, &gv, flags);
-    if (cv) {
-       if (CvCLONE(cv))
-           cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(cv_clone(cv))));
-    }
+    if (cv) NOOP;
     else if ((flags == (GV_ADD|GV_NOEXPAND)) && gv && SvROK(gv)) {
        cv = MUTABLE_CV(gv);
     }    
index 79ef361..d4c8b69 100644 (file)
@@ -313,6 +313,16 @@ foreach my $test (@tests) {
      'Calling closure proto with no @_ that returns a lexical';
 }
 
+# Referencing closure prototypes
+{
+  package buckbuck;
+  my @proto;
+  sub MODIFY_CODE_ATTRIBUTES { push @proto, $_[1], \&{$_[1]}; _: }
+  my $id;
+  () = sub :buck {$id};
+  &::is(@proto, 'referencing closure prototype');
+}
+
 # [perl #68658] Attributes on stately variables
 {
   package thwext;