Re: problem with rc1 and rc2 on Mac OS X
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index f001497..251fd8a 100644 (file)
--- a/sv.c
+++ b/sv.c
 
 #define FCALL *f
 
+#ifdef PERL_UTF8_CACHE_ASSERT
+/* The cache element 0 is the Unicode offset;
+ * the cache element 1 is the byte offset of the element 0;
+ * the cache element 2 is the Unicode length of the substring;
+ * the cache element 3 is the byte length of the substring;
+ * The checking of the substring side would be good
+ * but substr() has enough code paths to make my head spin;
+ * if adding more checks watch out for the following tests:
+ *   t/op/index.t t/op/length.t t/op/pat.t t/op/substr.t
+ *   lib/utf8.t lib/Unicode/Collate/t/index.t
+ * --jhi
+ */
+#define ASSERT_UTF8_CACHE(cache) \
+       STMT_START { if (cache) { assert((cache)[0] <= (cache)[1]); } } STMT_END
+#else
+#define ASSERT_UTF8_CACHE(cache) NOOP
+#endif
+
 #ifdef PERL_COPY_ON_WRITE
 #define SV_COW_NEXT_SV(sv)     INT2PTR(SV *,SvUVX(sv))
 #define SV_COW_NEXT_SV_SET(current,next)       SvUVX(current) = PTR2UV(next)
@@ -5091,7 +5109,9 @@ S_sv_add_backref(pTHX_ SV *tsv, SV *sv)
     else {
        av = newAV();
        sv_magic(tsv, (SV*)av, PERL_MAGIC_backref, NULL, 0);
-       SvREFCNT_dec(av);           /* for sv_magic */
+       /* av now has a refcnt of 2, which avoids it getting freed
+        * before us during global cleanup. The extra ref is removed
+        * by magic_killbackrefs() when tsv is being freed */
     }
     if (AvFILLp(av) >= AvMAX(av)) {
         SV **svp = AvARRAY(av);
@@ -5653,8 +5673,12 @@ Perl_sv_len_utf8(pTHX_ register SV *sv)
        U8 *s = (U8*)SvPV(sv, len);
        MAGIC *mg = SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : 0;
 
-       if (mg && mg->mg_len != -1 && (mg->mg_len > 0 || len == 0))
+       if (mg && mg->mg_len != -1 && (mg->mg_len > 0 || len == 0)) {
            ulen = mg->mg_len;
+#ifdef PERL_UTF8_CACHE_ASSERT
+           assert(ulen == Perl_utf8_length(aTHX_ s, s + len));
+#endif
+       }
        else {
            ulen = Perl_utf8_length(aTHX_ s, s + len);
            if (!mg && !SvREADONLY(sv)) {
@@ -5724,8 +5748,9 @@ S_utf8_mg_pos(pTHX_ SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, I
            *mgp = mg_find(sv, PERL_MAGIC_utf8);
        if (*mgp && (*mgp)->mg_ptr) {
            *cachep = (STRLEN *) (*mgp)->mg_ptr;
+           ASSERT_UTF8_CACHE(*cachep);
            if ((*cachep)[i] == (STRLEN)uoff)   /* An exact match. */
-                found = TRUE;
+                 found = TRUE;          
            else {                      /* We will skip to the right spot. */
                 STRLEN forw  = 0;
                 STRLEN backw = 0;
@@ -5797,7 +5822,24 @@ S_utf8_mg_pos(pTHX_ SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, I
                 }
            }
        }
+#ifdef PERL_UTF8_CACHE_ASSERT
+       if (found) {
+            U8 *s = start;
+            I32 n = uoff;
+
+            while (n-- && s < send)
+                 s += UTF8SKIP(s);
+
+            if (i == 0) {
+                 assert(*offsetp == s - start);
+                 assert((*cachep)[0] == (STRLEN)uoff);
+                 assert((*cachep)[1] == *offsetp);
+            }
+            ASSERT_UTF8_CACHE(*cachep);
+       }
+#endif
     }
+
     return found;
 }
  
@@ -5869,12 +5911,14 @@ Perl_sv_pos_u2b(pTHX_ register SV *sv, I32* offsetp, I32* lenp)
              }
              *lenp = s - start;
         }
+        ASSERT_UTF8_CACHE(cache);
     }
     else {
         *offsetp = 0;
         if (lenp)
              *lenp = 0;
     }
+
     return;
 }
 
@@ -5960,6 +6004,7 @@ Perl_sv_pos_b2u(pTHX_ register SV* sv, I32* offsetp)
                    }
                }
            }
+           ASSERT_UTF8_CACHE(cache);
        }
 
        while (s < send) {
@@ -8668,7 +8713,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
                    vecsv = va_arg(*args, SV*);
                else
                    vecsv = (evix ? evix <= svmax : svix < svmax) ?
-                       svargs[ewix ? ewix-1 : svix++] : &PL_sv_undef;
+                       svargs[evix ? evix-1 : svix++] : &PL_sv_undef;
                dotstr = SvPVx(vecsv, dotstrlen);
                if (DO_UTF8(vecsv))
                    is_utf8 = TRUE;
@@ -11269,6 +11314,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
     PL_glob_index      = proto_perl->Iglob_index;
     PL_srand_called    = proto_perl->Isrand_called;
+    PL_hash_seed       = proto_perl->Ihash_seed;
     PL_uudmap['M']     = 0;            /* reinits on demand */
     PL_bitcount                = Nullch;       /* reinits on demand */
 
@@ -11428,6 +11474,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_regstartp       = (I32*)NULL;
     PL_regendp         = (I32*)NULL;
     PL_reglastparen    = (U32*)NULL;
+    PL_reglastcloseparen       = (U32*)NULL;
     PL_regtill         = Nullch;
     PL_reg_start_tmp   = (char**)NULL;
     PL_reg_start_tmpl  = 0;