jvdias 0833027
--- perl-5.8.8/sv.c.U27512	2006-06-01 18:43:19.000000000 -0400
jvdias 0833027
+++ perl-5.8.8/sv.c	2006-06-01 19:13:32.000000000 -0400
jvdias 0833027
@@ -7993,6 +7993,52 @@
jvdias 0833027
     return rv;
jvdias 0833027
 }
jvdias 0833027
 
jvdias 0833027
+/* This is a hack to cope with reblessing from class with overloading magic to
jvdias 0833027
+   one without (or the other way).  Search for every reference pointing to the
jvdias 0833027
+   object.  Can't use S_visit() because we would need to pass a parameter to
jvdias 0833027
+   our function.  */
jvdias 0833027
+static void
jvdias 0833027
+S_reset_amagic(pTHX_ SV *rv, const bool on) {
jvdias 0833027
+    /* It is assumed that you've already turned magic on/off on rv  */
jvdias 0833027
+    SV* sva;
jvdias 0833027
+    SV *const target = SvRV(rv);
jvdias 0833027
+    /* Less 1 for the reference we've already dealt with.  */
jvdias 0833027
+    U32 how_many = SvREFCNT(target) - 1;
jvdias 0833027
+    MAGIC *mg;
jvdias 0833027
+
jvdias 0833027
+    if (SvMAGICAL(target) && (mg = mg_find(target, PERL_MAGIC_backref))) {
jvdias 0833027
+	/* Back referneces also need to be found, but aren't part of the
jvdias 0833027
+	   target's reference count.  */
jvdias 0833027
+	how_many += 1 + av_len((AV*)mg->mg_obj);
jvdias 0833027
+    }
jvdias 0833027
+
jvdias 0833027
+    if (!how_many) {
jvdias 0833027
+	/* There was only 1 reference to this object.  */
jvdias 0833027
+	return;
jvdias 0833027
+    }
jvdias 0833027
+
jvdias 0833027
+    for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) {
jvdias 0833027
+	register const SV * const svend = &sva[SvREFCNT(sva)];
jvdias 0833027
+	register SV* sv;
jvdias 0833027
+	for (sv = sva + 1; sv < svend; ++sv) {
jvdias 0833027
+	    if (SvTYPE(sv) != SVTYPEMASK
jvdias 0833027
+		&& (sv->sv_flags & SVf_ROK) == SVf_ROK
jvdias 0833027
+		&& SvREFCNT(sv)
jvdias 0833027
+		&& SvRV(sv) == target
jvdias 0833027
+		&& sv != rv) {
jvdias 0833027
+		if (on)
jvdias 0833027
+		    SvAMAGIC_on(sv);
jvdias 0833027
+		else
jvdias 0833027
+		    SvAMAGIC_off(sv);
jvdias 0833027
+		if (--how_many == 0) {
jvdias 0833027
+		    /* We have found them all.  */
jvdias 0833027
+		    return;
jvdias 0833027
+		}
jvdias 0833027
+	    }
jvdias 0833027
+	}
jvdias 0833027
+    }
jvdias 0833027
+}
jvdias 0833027
+
jvdias 0833027
 /*
jvdias 0833027
 =for apidoc sv_bless
jvdias 0833027
 
jvdias 0833027
@@ -8025,10 +8071,17 @@
jvdias 0833027
     (void)SvUPGRADE(tmpRef, SVt_PVMG);
jvdias 0833027
     SvSTASH_set(tmpRef, (HV*)SvREFCNT_inc(stash));
jvdias 0833027
 
jvdias 0833027
-    if (Gv_AMG(stash))
jvdias 0833027
-	SvAMAGIC_on(sv);
jvdias 0833027
-    else
jvdias 0833027
-	SvAMAGIC_off(sv);
jvdias 0833027
+    if (Gv_AMG(stash)) {
jvdias 0833027
+	if (!SvAMAGIC(sv)) {
jvdias 0833027
+	    SvAMAGIC_on(sv);
jvdias 0833027
+	    S_reset_amagic(aTHX_ sv, TRUE);
jvdias 0833027
+	}
jvdias 0833027
+    } else {
jvdias 0833027
+	if (SvAMAGIC(sv)) {
jvdias 0833027
+	    SvAMAGIC_off(sv);
jvdias 0833027
+	    S_reset_amagic(aTHX_ sv, FALSE);
jvdias 0833027
+	}
jvdias 0833027
+    }
jvdias 0833027
 
jvdias 0833027
     if(SvSMAGICAL(tmpRef))
jvdias 0833027
         if(mg_find(tmpRef, PERL_MAGIC_ext) || mg_find(tmpRef, PERL_MAGIC_uvar))
jvdias 0833027
--- perl-5.8.8/proto.h.U27512	2006-06-01 18:43:19.000000000 -0400
jvdias 0833027
+++ perl-5.8.8/proto.h	2006-06-01 19:13:32.000000000 -0400
jvdias 0833027
@@ -1875,6 +1875,7 @@
jvdias 0833027
 #
jvdias 0833027
 STATIC bool	S_utf8_mg_pos(pTHX_ SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, I32 uoff, const U8 **sp, const U8 *start, const U8 *send);
jvdias 0833027
 STATIC bool	S_utf8_mg_pos_init(pTHX_ SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 offsetp, const U8 *s, const U8 *start);
jvdias 0833027
+STATIC void	S_reset_amagic(pTHX_ SV *rv, const bool on);
jvdias 0833027
 #endif
jvdias 0833027
 
jvdias 0833027
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)
jvdias 0833027
--- perl-5.8.8/embed.h.U27512	2006-06-01 18:43:19.000000000 -0400
jvdias 0833027
+++ perl-5.8.8/embed.h	2006-06-01 19:13:32.000000000 -0400
jvdias 0833027
@@ -1348,6 +1348,7 @@
jvdias 0833027
 #ifdef PERL_CORE
jvdias 0833027
 #define utf8_mg_pos		S_utf8_mg_pos
jvdias 0833027
 #define utf8_mg_pos_init	S_utf8_mg_pos_init
jvdias 0833027
+#define reset_amagic		S_reset_amagic
jvdias 0833027
 #endif
jvdias 0833027
 #endif
jvdias 0833027
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)
jvdias 0833027
@@ -3390,6 +3391,7 @@
jvdias 0833027
 #ifdef PERL_CORE
jvdias 0833027
 #define utf8_mg_pos(a,b,c,d,e,f,g,h,i)	S_utf8_mg_pos(aTHX_ a,b,c,d,e,f,g,h,i)
jvdias 0833027
 #define utf8_mg_pos_init(a,b,c,d,e,f,g)	S_utf8_mg_pos_init(aTHX_ a,b,c,d,e,f,g)
jvdias 0833027
+#define reset_amagic(a,b)	S_reset_amagic(aTHX_ a,b)
jvdias 0833027
 #endif
jvdias 0833027
 #endif
jvdias 0833027
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)
jvdias 0833027
--- perl-5.8.8/embed.fnc.U27512	2006-06-01 18:43:19.000000000 -0400
jvdias 0833027
+++ perl-5.8.8/embed.fnc	2006-06-01 19:13:32.000000000 -0400
jvdias 0833027
@@ -1276,6 +1276,7 @@
jvdias 0833027
 s	|bool	|utf8_mg_pos_init	|NN SV *sv|NN MAGIC **mgp \
jvdias 0833027
 				|NN STRLEN **cachep|I32 i|I32 offsetp \
jvdias 0833027
 				|NN const U8 *s|NN const U8 *start
jvdias 0833027
+s	|void	|reset_amagic	|NN SV *rv|const bool on
jvdias 0833027
 #endif
jvdias 0833027
 
jvdias 0833027
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)