# New Ticket Created by  Leopold Toetsch 
# Please include the string:  [perl #17703]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=17703 >


Description of patch by chunks:
- remove outdated comment/ifdef
- use Parrot_allocate_string in unmake_COW. The currently used method is 
not wrong, but hides, that Parrot_reallocate_string in alloc/copy 
internally. Also resets BUFFER_external_flag, which was set for COWed 
constants.
- save some cycles in strlen
- string_to_cstring returned (Peter) highly volatile pointers.

Please apply,
leo


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/38995/31667/629f2d/string_c.patch

--- parrot/string.c     Sun Sep 15 15:30:59 2002
+++ parrot-leo/string.c Tue Oct  1 08:29:04 2002
@@ -18,32 +18,31 @@
 #define EXTRA_SIZE 4
 
 /* String COW support */
+
+/* make a copy of string's data:
+ * copy used string data from strstart to a newly
+ * allocated string
+ * the header stays the same
+ */
 static void
 unmake_COW(struct Parrot_Interp *interpreter, STRING *s)
 {
-#if 0
-    if (s->flags & BUFFER_constant_FLAG) {
-        /* this happens when we call string_to_cstring on 
-         * a constant string in order to print it
-         */
-        internal_exception(INVALID_OPERATION,
-                           "Cannot unmake COW on a constant header");
-    }
-    else
-#endif
     if (s->flags & (BUFFER_COW_FLAG|BUFFER_constant_FLAG)) {
+        void *p;
+        UINTVAL size;
         interpreter->GC_block_level++;
         interpreter->DOD_block_level++;
 
         /* Make the copy point to only the portion of the string that
          * we are actually using. */
-        s->bufstart = s->strstart;
-        s->buflen = s->bufused;
-
+        p = s->strstart;
+        size = s->bufused;
         /* Create new pool data for this header to use, 
          * independant of the original COW data */
-        Parrot_reallocate_string(interpreter, s, s->buflen);
-        s->flags &= ~(UINTVAL)(BUFFER_COW_FLAG | BUFFER_constant_FLAG);
+        Parrot_allocate_string(interpreter, s, s->buflen);
+        mem_sys_memcopy(s->bufstart, p, size);
+        s->flags &= ~(UINTVAL)(BUFFER_COW_FLAG | BUFFER_constant_FLAG |
+                BUFFER_external_FLAG);
         interpreter->GC_block_level--;
         interpreter->DOD_block_level--;
     }
@@ -399,8 +398,7 @@
 INTVAL
 string_compute_strlen(STRING *s)
 {
-    s->strlen = s->encoding->characters(s->bufstart, s->bufused) - 
-        ((UINTVAL)s->strstart - (UINTVAL)s->bufstart);
+    s->strlen = s->encoding->characters(s->strstart, s->bufused);
     return s->strlen;
 }
 
@@ -972,13 +970,6 @@
 const char *
 string_to_cstring(struct Parrot_Interp * interpreter, STRING * s)
 {
-    char *cstring;
-
-    /* We shouldn't modify a constant string, 
-     * so instead create a new copy of it */
-    if (s->flags & BUFFER_constant_FLAG) {
-        s = make_COW_reference(interpreter,s);
-    }
 
     unmake_COW(interpreter, s);
 
@@ -986,11 +977,9 @@
         string_grow(interpreter, s, 1);
     }
 
-    cstring = s->strstart;
-
-    cstring[s->bufused] = 0;
-
-    return cstring;
+    ((char *)s->strstart)[s->bufused] = 0;
+    /* don't return local vars, return the right thing */
+    return (char*)s->strstart;
 }
 
 

Reply via email to