# 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;
}