This is yet another variant of the cashing-RE patch.

Now, when all the things which were broken by the previous versions of
this patch are checked by the test suite, it may have a better chance
of survival.

However, it may happen that Gurusamy's fingers are too tired from
constant including/excluding of this patch into 5.005_tobe  ;-).

Enjoy,
Ilya

--- ./sv.c.orig	Tue Jun 23 02:06:30 1998
+++ ./sv.c	Sat Jun 27 01:22:17 1998
@@ -1710,7 +1710,7 @@ sv_2pv(register SV *sv, STRLEN *lp)
 		case SVt_PVMG:
 		    if ( ((SvFLAGS(sv) &
 			   (SVs_OBJECT|SVf_OK|SVs_GMG|SVs_SMG|SVs_RMG)) 
-			  == (SVs_OBJECT|SVs_RMG))
+			  == (SVs_OBJECT|SVs_RMG|SVs_SMG))
 			 && strEQ(s=HvNAME(SvSTASH(sv)), "Regexp")
 			 && (mg = mg_find(sv, 'r'))) {
 			regexp *re = (regexp *)mg->mg_obj;
@@ -2583,6 +2583,7 @@ sv_magic(register SV *sv, SV *obj, int h
 	mg->mg_virtual = &vtbl_packelem;
 	break;
     case 'r':
+	SvRMAGICAL_on(sv);
 	mg->mg_virtual = &vtbl_regexp;
 	break;
     case 'S':
--- ./proto.h.orig	Fri Jun 26 18:37:15 1998
+++ ./proto.h	Sat Jun 27 00:29:45 1998
@@ -261,6 +261,7 @@ VIRTUAL int	magic_setuvar	_((SV* sv, MAG
 VIRTUAL int	magic_setvec	_((SV* sv, MAGIC* mg));
 VIRTUAL int	magic_set_all_env _((SV* sv, MAGIC* mg));
 VIRTUAL U32	magic_sizepack	_((SV* sv, MAGIC* mg));
+VIRTUAL int	magic_unchain	_((SV* sv, MAGIC* mg));
 VIRTUAL int	magic_wipepack	_((SV* sv, MAGIC* mg));
 VIRTUAL void	magicname _((char* sym, char* name, I32 namlen));
 int	main _((int argc, char** argv, char** env));
--- ./pp_ctl.c.orig	Fri Jun 26 20:59:18 1998
+++ ./pp_ctl.c	Sat Jun 27 00:33:34 1998
@@ -76,8 +76,8 @@ PP(pp_regcomp) {
     MAGIC *mg = Null(MAGIC*);
 
     tmpstr = POPs;
-    if(SvROK(tmpstr)) {
-	SV *sv = SvRV(tmpstr);
+    if(SvROK(tmpstr) || SvRMAGICAL(tmpstr)) {
+	SV *sv = SvROK(tmpstr) ? SvRV(tmpstr) : tmpstr;
 	if(SvMAGICAL(sv))
 	    mg = mg_find(sv, 'r');
     }
@@ -101,6 +101,8 @@ PP(pp_regcomp) {
 
 	    pm->op_pmflags = pm->op_pmpermflags;	/* reset case sensitivity */
 	    pm->op_pmregexp = pregcomp(t, t + len, pm);
+	    if (!(SvFLAGS(tmpstr) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)))
+		sv_magic(tmpstr,(SV*)ReREFCNT_inc(pm->op_pmregexp),'r',0,0);
 	}
     }
 
--- ./global.sym.orig	Fri Jun 26 18:37:15 1998
+++ ./global.sym	Sat Jun 27 00:29:45 1998
@@ -424,6 +424,7 @@ magic_settaint
 magic_setuvar
 magic_setvec
 magic_sizepack
+magic_unchain
 magic_wipepack
 magicname
 malloced_size
--- ./mg.c.orig	Thu Jun 18 15:40:53 1998
+++ ./mg.c	Sat Jun 27 00:29:45 1998
@@ -1511,6 +1511,13 @@ magic_freeregexp(SV *sv, MAGIC *mg)
     return 0;
 }
 
+int
+magic_unchain(SV *sv, MAGIC *mg)
+{
+    sv_unmagic(sv, mg->mg_type);
+    return 0;
+}
+
 #ifdef USE_LOCALE_COLLATE
 int
 magic_setcollxfrm(SV *sv, MAGIC *mg)
--- ./perl.h.orig	Fri Jun 26 18:37:15 1998
+++ ./perl.h	Sat Jun 27 00:29:45 1998
@@ -2050,7 +2050,7 @@ EXT MGVTBL vtbl_mutex =	{0,	0,	0,	0,	mag
 EXT MGVTBL vtbl_defelem = {magic_getdefelem,magic_setdefelem,
 					0,	0,	magic_freedefelem};
 
-EXT MGVTBL vtbl_regexp = {0,0,0,0, magic_freeregexp};
+EXT MGVTBL vtbl_regexp = {0,magic_unchain,0,0, magic_freeregexp};
 
 #ifdef USE_LOCALE_COLLATE
 EXT MGVTBL vtbl_collxfrm = {0,
