}
}
+/* ... Saving code slots from a glob ....................................... */
+
+#if SU_HAS_PERL(5, 13, 10)
+
+/* Since perl 5.13.10, GvCV() is only a rvalue so we no longer can store a
+ * pointer to the gvcv member of the gv. */
+
+typedef struct {
+ GV *gv;
+ CV *old_cv;
+} su_save_gvcv_ud;
+
+STATIC void su_restore_gvcv(pTHX_ void *ud_) {
+ su_save_gvcv_ud *ud = ud_;
+
+ GvCV_set(ud->gv, ud->old_cv);
+
+ Safefree(ud);
+}
+
+STATIC void su_save_gvcv(pTHX_ GV *gv) {
+#define su_save_gvcv(gv) su_save_gvcv(aTHX_ (gv))
+ su_save_gvcv_ud *ud;
+
+ Newx(ud, 1, su_save_gvcv_ud);
+ ud->gv = gv;
+ ud->old_cv = GvCV(gv);
+
+ GvCV_set(gv, NULL);
+
+ SAVEDESTRUCTOR_X(su_restore_gvcv, ud);
+}
+
+#else
+
+#define su_save_gvcv(gv) SAVESPTR(GvCV(gv)), GvCV_set((gv), NULL)
+
+#endif
+
/* --- Actions ------------------------------------------------------------- */
typedef struct {
save_gp(gv, 1); /* hide previous entry in symtab */
break;
case SVt_PVCV:
- SAVESPTR(GvCV(gv));
- GvCV_set(gv, NULL);
+ su_save_gvcv(gv);
break;
default:
gv = (GV *) save_scalar(gv);
use strict;
use warnings;
-use Test::More tests => 50 + 4;
+use Test::More tests => 61 + 4;
use Scope::Upper qw/localize UP HERE/;
is foo(), 8, 'localize "&foo", sub { 8 } => UP [ok]';
}
+{
+ local *foo = sub { 'a' };
+ {
+ {
+ localize *foo, sub { 'b' } => UP;
+ is foo(), 'a', 'localize *foo, sub { "b" } => UP [not yet 1]';
+ {
+ no warnings 'redefine';
+ local *foo = sub { 'c' };
+ is foo(), 'c', 'localize *foo, sub { "b" } => UP [localized 1]';
+ }
+ is foo(), 'a', 'localize *foo, sub { "b" } => UP [not yet 2]';
+ }
+ is foo(), 'b', 'localize *foo, sub { "b" } => UP [ok 1]';
+ {
+ no warnings 'redefine';
+ local *foo = sub { 'd' };
+ is foo(), 'd', 'localize *foo, sub { "b" } => UP [localized 2]';
+ }
+ is foo(), 'b', 'localize *foo, sub { "b" } => UP [ok 2]';
+ }
+ is foo(), 'a', 'localize *foo, sub { "b" } => UP [end]';
+}
+
+{
+ local *foo = sub { 'x' };
+ {
+ {
+ localize *foo, sub { 'y' } => UP;
+ is foo(), 'x', 'localize *foo, sub { "y" } => UP [not yet]';
+ }
+ is foo(), 'y', 'localize *foo, sub { "y" } => UP [ok]';
+ no warnings 'redefine';
+ *foo = sub { 'z' };
+ is foo(), 'z', 'localize *foo, sub { "y" } => UP [replaced]';
+ }
+ is foo(), 'x', 'localize *foo, sub { "y" } => UP [end]';
+}
+
# Invalid
sub invalid_ref { qr/^Invalid \Q$_[0]\E reference as the localization target/ }