[svn:parrot] r45852 - in trunk: . compilers/imcc config/gen/makefiles docs docs/pdds include/parrot lib/Parrot lib/Parrot/Configure/Options/Test lib/Parrot/Pmc2c src src/call src/io src/ops src/packfile src/pmc src/runcore src/string src/string/charset src/string/encoding t/native_pbc t/op t/pmc tools/dev

bacek at svn.parrot.org bacek at svn.parrot.org
Wed Apr 21 10:06:04 UTC 2010


Author: bacek
Date: Wed Apr 21 10:06:00 2010
New Revision: 45852
URL: https://trac.parrot.org/parrot/changeset/45852

Log:
Everybody freeze! Immutable strings enters the building.

Merge branch immutable_strings_part1 back to trunk.

Modified:
   trunk/MANIFEST.SKIP
   trunk/PBC_COMPAT
   trunk/compilers/imcc/parser_util.c
   trunk/config/gen/makefiles/root.in
   trunk/docs/embed.pod
   trunk/docs/pdds/pdd28_strings.pod
   trunk/include/parrot/charset.h
   trunk/include/parrot/encoding.h
   trunk/include/parrot/io.h
   trunk/include/parrot/string_funcs.h
   trunk/include/parrot/string_primitives.h
   trunk/lib/Parrot/Configure/Options/Test/Prepare.pm
   trunk/lib/Parrot/Distribution.pm
   trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
   trunk/src/call/args.c
   trunk/src/dynext.c
   trunk/src/hash.c
   trunk/src/hll.c
   trunk/src/io/api.c
   trunk/src/io/buffer.c
   trunk/src/io/filehandle.c
   trunk/src/io/utf8.c
   trunk/src/io/win32.c
   trunk/src/key.c
   trunk/src/library.c
   trunk/src/ops/bit.ops
   trunk/src/ops/ops.num
   trunk/src/ops/set.ops
   trunk/src/ops/string.ops
   trunk/src/packdump.c
   trunk/src/packfile.c
   trunk/src/packfile/pf_items.c
   trunk/src/pbc_dump.c
   trunk/src/pmc/bigint.pmc
   trunk/src/pmc/bignum.pmc
   trunk/src/pmc/callcontext.pmc
   trunk/src/pmc/class.pmc
   trunk/src/pmc/codestring.pmc
   trunk/src/pmc/coroutine.pmc
   trunk/src/pmc/eventhandler.pmc
   trunk/src/pmc/filehandle.pmc
   trunk/src/pmc/fixedbooleanarray.pmc
   trunk/src/pmc/fixedintegerarray.pmc
   trunk/src/pmc/fixedpmcarray.pmc
   trunk/src/pmc/fixedstringarray.pmc
   trunk/src/pmc/hash.pmc
   trunk/src/pmc/key.pmc
   trunk/src/pmc/namespace.pmc
   trunk/src/pmc/object.pmc
   trunk/src/pmc/packfiledirectory.pmc
   trunk/src/pmc/parrotinterpreter.pmc
   trunk/src/pmc/pmcproxy.pmc
   trunk/src/pmc/resizablepmcarray.pmc
   trunk/src/pmc/role.pmc
   trunk/src/pmc/scalar.pmc
   trunk/src/pmc/string.pmc
   trunk/src/pmc/stringhandle.pmc
   trunk/src/pmc/sub.pmc
   trunk/src/runcore/profiling.c
   trunk/src/spf_render.c
   trunk/src/spf_vtable.c
   trunk/src/string/api.c
   trunk/src/string/charset.c
   trunk/src/string/charset/ascii.c
   trunk/src/string/charset/ascii.h
   trunk/src/string/charset/binary.c
   trunk/src/string/charset/binary.h
   trunk/src/string/charset/iso-8859-1.c
   trunk/src/string/charset/iso-8859-1.h
   trunk/src/string/charset/unicode.c
   trunk/src/string/charset/unicode.h
   trunk/src/string/encoding/fixed_8.c
   trunk/src/string/encoding/fixed_8.h
   trunk/src/string/encoding/ucs2.c
   trunk/src/string/encoding/ucs2.h
   trunk/src/string/encoding/utf16.c
   trunk/src/string/encoding/utf16.h
   trunk/src/string/encoding/utf8.c
   trunk/src/string/encoding/utf8.h
   trunk/src/string/primitives.c
   trunk/src/sub.c
   trunk/t/native_pbc/annotations.pbc
   trunk/t/native_pbc/integer_1.pbc
   trunk/t/native_pbc/number_1.pbc
   trunk/t/native_pbc/string_1.pbc
   trunk/t/op/string.t
   trunk/t/pmc/string.t
   trunk/tools/dev/pbc_to_exe.pir

Modified: trunk/MANIFEST.SKIP
==============================================================================
--- trunk/MANIFEST.SKIP	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/MANIFEST.SKIP	Wed Apr 21 10:06:00 2010	(r45852)
@@ -65,8 +65,8 @@
 ^all_cstring\.str/
 ^blib$
 ^blib/
-^config_lib\.pir$
-^config_lib\.pir/
+^config_lib\.pasm$
+^config_lib\.pasm/
 ^cover_db$
 ^cover_db/
 ^install_config\.fpmc$
@@ -616,9 +616,6 @@
 # generated from svn:ignore of 'runtime/parrot/library/String/'
 ^runtime/parrot/library/String/Utils\.pbc$
 ^runtime/parrot/library/String/Utils\.pbc/
-# generated from svn:ignore of 'runtime/parrot/library/TAP/'
-^runtime/parrot/library/TAP/.*\.pbc$
-^runtime/parrot/library/TAP/.*\.pbc/
 # generated from svn:ignore of 'runtime/parrot/library/Tcl/'
 ^runtime/parrot/library/Tcl/.*\.pbc$
 ^runtime/parrot/library/Tcl/.*\.pbc/

Modified: trunk/PBC_COMPAT
==============================================================================
--- trunk/PBC_COMPAT	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/PBC_COMPAT	Wed Apr 21 10:06:00 2010	(r45852)
@@ -27,6 +27,7 @@
 
 # please insert tab separated entries at the top of the list
 
+6.6	2010.04.17	bacek	add replace op
 6.5	2010.03.09	cotto	remove cpu_ret op
 6.4	2010.03.02	cotto	remove prederef__ and reserved
 6.3	2010.02.16	whiteknight	Add OpLib and Opcode PMCs

Modified: trunk/compilers/imcc/parser_util.c
==============================================================================
--- trunk/compilers/imcc/parser_util.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/compilers/imcc/parser_util.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -708,7 +708,7 @@
         sub_data->seg        = new_cs;
         sub_data->start_offs = 0;
         sub_data->end_offs   = new_cs->base.size;
-        sub_data->name       = Parrot_str_copy(interp, name);
+        sub_data->name       = name;
 
         *error_message = NULL;
     }

Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/config/gen/makefiles/root.in	Wed Apr 21 10:06:00 2010	(r45852)
@@ -2559,11 +2559,11 @@
 tags-vi: tags.vi.dummy
 	$(RM_F) tags
 	@ctags@ \
-    --links=no --totals \
-    -R --exclude=blib --exclude=.svn  \
-    --languages=c,perl --langmap=c:+.h,c:+.pmc,c:+.ops \
-    -I NOTNULL,NULLOK,ARGIN,ARGMOD,ARGOUT,ARGINOUT,ARGIN_NULLOK,ARGOUT_NULLOK,ARGMOD_NULLOK,ARGFREE,ARGFREE_NOTNULL \
-    .
+	--links=no --totals \
+	-R --exclude=blib --exclude=.svn  \
+	--languages=c,perl --langmap=c:+.h,c:+.pmc,c:+.ops \
+	-I NOTNULL,NULLOK,ARGIN,ARGMOD,ARGOUT,ARGINOUT,ARGIN_NULLOK,ARGOUT_NULLOK,ARGMOD_NULLOK,ARGFREE,ARGFREE_NOTNULL \
+	.
 	$(PERL) $(BUILD_TOOLS_DIR)/addopstags.pl $(OPS_FILES)
 
 tags.vi.dummy:
@@ -2575,6 +2575,7 @@
 
 # Andy's extra-cranky Perl::Critic checking for cage cleaners
 cagecritic:
+	@perl -MPerl::Critic::Bangs -e'$$min=q{1.04};die qq{You need Bangs $$min} unless $$Perl::Critic::Bangs::VERSION ge $$min'
 	perlcritic -1 --profile tools/util/perlcritic-cage.conf $(CRITIC_FILES)
 
 # This target will eventually create all the headers automatically.  If you

Modified: trunk/docs/embed.pod
==============================================================================
--- trunk/docs/embed.pod	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/docs/embed.pod	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1551,8 +1551,6 @@
 
 =item C<Parrot_store_sub_in_namespace>
 
-=item C<Parrot_str_append>
-
 =item C<Parrot_str_boolean>
 
 =item C<Parrot_str_byte_length>

Modified: trunk/docs/pdds/pdd28_strings.pod
==============================================================================
--- trunk/docs/pdds/pdd28_strings.pod	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/docs/pdds/pdd28_strings.pod	Wed Apr 21 10:06:00 2010	(r45852)
@@ -379,13 +379,6 @@
 value of flags. If both string arguments are null, return a new string created
 according to the integer flags.
 
-=head4 Parrot_str_append (was string_append)
-
-Append one string to another and return the result. In the default case, the
-return value is the same as the first string argument (modifying that argument
-in place). If the first argument is COW or read-only, then the return value is
-a new string.
-
 =head4 Parrot_str_new (was string_from_cstring)
 
 Return a new string with the default encoding and character set. Accepts two

Modified: trunk/include/parrot/charset.h
==============================================================================
--- trunk/include/parrot/charset.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/include/parrot/charset.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -34,19 +34,17 @@
 #define PARROT_UNICODE_CHARSET Parrot_unicode_charset_ptr
 
 typedef STRING *(*charset_get_graphemes_t)(PARROT_INTERP, STRING *source_string, UINTVAL offset, UINTVAL count);
-typedef STRING *(*charset_get_graphemes_inplace_t)(PARROT_INTERP, STRING *source_string, UINTVAL offset, UINTVAL count, STRING *dest_string);
-typedef void (*charset_set_graphemes_t)(PARROT_INTERP, STRING *source_string, UINTVAL offset, UINTVAL replace_count, STRING *insert_string);
 
-typedef STRING * (*charset_to_charset_t)(PARROT_INTERP, STRING *source_string, STRING *dest);
-typedef STRING * (*charset_from_unicode_t)(PARROT_INTERP, STRING *source_string, STRING *dest);
+typedef STRING * (*charset_to_charset_t)(PARROT_INTERP, STRING *source_string);
+typedef STRING * (*charset_from_unicode_t)(PARROT_INTERP, STRING *source_string);
 typedef STRING* (*charset_compose_t)(PARROT_INTERP, STRING *source_string);
 typedef STRING* (*charset_decompose_t)(PARROT_INTERP, STRING *source_string);
-typedef void (*charset_upcase_t)(PARROT_INTERP, STRING *source_string);
-typedef void (*charset_downcase_t)(PARROT_INTERP, STRING *source_string);
-typedef void (*charset_titlecase_t)(PARROT_INTERP, STRING *source_string);
-typedef void (*charset_upcase_first_t)(PARROT_INTERP, STRING *source_string);
-typedef void (*charset_downcase_first_t)(PARROT_INTERP, STRING *source_string);
-typedef void (*charset_titlecase_first_t)(PARROT_INTERP, STRING *source_string);
+typedef STRING* (*charset_upcase_t)(PARROT_INTERP, const STRING *source_string);
+typedef STRING* (*charset_downcase_t)(PARROT_INTERP, const STRING *source_string);
+typedef STRING* (*charset_titlecase_t)(PARROT_INTERP, const STRING *source_string);
+typedef STRING* (*charset_upcase_first_t)(PARROT_INTERP, const STRING *source_string);
+typedef STRING* (*charset_downcase_first_t)(PARROT_INTERP, const STRING *source_string);
+typedef STRING* (*charset_titlecase_first_t)(PARROT_INTERP, const STRING *source_string);
 typedef INTVAL (*charset_compare_t)(PARROT_INTERP, const STRING *lhs, const STRING *rhs);
 typedef INTVAL (*charset_index_t)(PARROT_INTERP, STRING *source_string, STRING *search_string, UINTVAL offset);
 typedef INTVAL (*charset_rindex_t)(PARROT_INTERP, STRING *source_string, STRING *search_string, UINTVAL offset);
@@ -73,7 +71,7 @@
 typedef STRING *(*charset_string_from_codepoint_t)(PARROT_INTERP, UINTVAL codepoint);
 typedef size_t (*charset_compute_hash_t)(PARROT_INTERP, const STRING *, size_t seed);
 
-typedef STRING* (*charset_converter_t)(PARROT_INTERP, STRING *src, STRING *dst);
+typedef STRING* (*charset_converter_t)(PARROT_INTERP, STRING *src);
 
 /* HEADERIZER BEGIN: src/string/charset.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
@@ -86,7 +84,7 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-STRING* Parrot_charset_name(SHIM_INTERP, INTVAL number_of_charset);
+STRING * Parrot_charset_name(SHIM_INTERP, INTVAL number_of_charset);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
@@ -137,18 +135,19 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-CHARSET * Parrot_load_charset(PARROT_INTERP, ARGIN(const char *charsetname))
+const CHARSET * Parrot_load_charset(PARROT_INTERP,
+    ARGIN(const char *charsetname))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
 INTVAL Parrot_make_default_charset(SHIM_INTERP,
     SHIM(const char *charsetname),
-    ARGIN(CHARSET *charset))
+    ARGIN(const CHARSET *charset))
         __attribute__nonnull__(3);
 
 PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
+PARROT_CANNOT_RETURN_NULL
 PARROT_MALLOC
 CHARSET * Parrot_new_charset(PARROT_INTERP)
         __attribute__nonnull__(1);
@@ -164,7 +163,7 @@
 PARROT_EXPORT
 void Parrot_register_charset_converter(PARROT_INTERP,
     ARGIN(const CHARSET *lhs),
-    ARGIN(CHARSET *rhs),
+    ARGIN(const CHARSET *rhs),
     ARGIN(charset_converter_t func))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -214,8 +213,6 @@
 struct _charset {
     const char *name;
     charset_get_graphemes_t get_graphemes;
-    charset_get_graphemes_inplace_t get_graphemes_inplace;
-    charset_set_graphemes_t set_graphemes;
     charset_to_charset_t to_charset;
     charset_compose_t compose;
     charset_decompose_t decompose;
@@ -238,8 +235,6 @@
 };
 
 #define CHARSET_GET_GRAPEMES(interp, source, offset, count) ((source)->charset)->get_graphemes((interp), (source), (offset), (count))
-#define CHARSET_GET_GRAPHEMES_INPLACE(interp, source, dest, offset, count) ((source)->charset)->get_graphemes((interp), (source), (dest), (offset), (count))
-#define CHARSET_SET_GRAPHEMES(interp, source, offset, replace_count, insert) ((source)->charset)->set_graphemes((interp), (source), (offset), (replace_count), (insert))
 #define CHARSET_TO_UNICODE(interp, source, dest) ((source)->charset)->to_unicode((interp), (source), (dest))
 #define CHARSET_COMPOSE(interp, source) ((source)->charset)->compose((interp), (source))
 #define CHARSET_DECOMPOSE(interp, source) ((source)->charset)->decompose((interp), (source))
@@ -262,16 +257,10 @@
 #define CHARSET_TO_ENCODING(interp, source) ((source)->encoding)->to_encoding((interp), (source))
 #define CHARSET_COPY_TO_ENCODING(interp, source) ((source)->encoding)->copy_to_encoding((interp), (source))
 #define CHARSET_GET_CODEPOINT(interp, source, offset) ((source)->encoding)->get_codepoint((interp), (source), (offset))
-#define CHARSET_SET_CODEPOINT(interp, source, offset, codepoint) ((source)->encoding)->set_codepoint((interp), (source), (offset), (codepoint))
 #define CHARSET_GET_BYTE(interp, source, offset) ((source)->encoding)->get_byte((interp), (source), (offset))
 #define CHARSET_SET_BYTE(interp, source, offset, value) ((source)->encoding)->set_byte((interp), (source), (offset), (value))
 #define CHARSET_GET_CODEPOINTS(interp, source, offset, count) ((source)->encoding)->get_codepoints((interp), (source), (offset), (count))
-#define CHARSET_GET_CODEPOINTS_INPLACE(interp, source, dest, offset, count) ((source)->encoding)->get_codepoints_inplace((interp), (source), (dest), (offset), (count))
 #define CHARSET_GET_BYTES(interp, source, offset, count) ((source)->encoding)->get_bytes((interp), (source), (offset), (count))
-#define CHARSET_GET_BYTES_INPLACE(interp, source, offset, count, dest) ((source)->encoding)->get_bytes((interp), (source), (offset), (count), (dest))
-#define CHARSET_SET_CODEPOINTS(interp, source, offset, count, newdata) ((source)->encoding)->set_codepoints((interp), (source), (offset), (count), (newdata))
-#define CHARSET_SET_BYTES(interp, source, offset, count, newdata) ((source)->encoding)->set_bytes((interp), (source), (offset), (count), (newdata))
-#define CHARSET_BECOME_ENCODING(interp, source) ((source)->encoding)->become_encoding((interp), (source))
 #define CHARSET_CODEPOINTS(interp, source) ((source)->encoding)->codepoints((interp), (source))
 #define CHARSET_BYTES(interp, source) ((source)->encoding)->bytes((interp), (source))
 

Modified: trunk/include/parrot/encoding.h
==============================================================================
--- trunk/include/parrot/encoding.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/include/parrot/encoding.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -15,20 +15,14 @@
 
 #include "parrot/parrot.h"
 
-typedef STRING * (*encoding_to_encoding_t)(PARROT_INTERP, NOTNULL(STRING *src), NULLOK(STRING *dest));
+typedef STRING * (*encoding_to_encoding_t)(PARROT_INTERP, NOTNULL(const STRING *src));
 typedef UINTVAL (*encoding_get_codepoint_t)(PARROT_INTERP, const STRING *src, UINTVAL offset);
-typedef void (*encoding_set_codepoint_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL codepoint);
 typedef UINTVAL (*encoding_get_byte_t)(PARROT_INTERP, const STRING *src, UINTVAL offset);
 typedef void (*encoding_set_byte_t)(PARROT_INTERP, const STRING *src, UINTVAL offset, UINTVAL count);
 typedef STRING *(*encoding_get_codepoints_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL count);
 typedef STRING *(*encoding_get_bytes_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL count);
-typedef STRING *(*encoding_get_codepoints_inplace_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL count, STRING *dest_string);
-typedef STRING *(*encoding_get_bytes_inplace_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL count, STRING *dest_string);
-typedef void (*encoding_set_codepoints_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL count, STRING *new_bytes);
-typedef void (*encoding_set_bytes_t)(PARROT_INTERP, STRING *src, UINTVAL offset, UINTVAL count, STRING *new_bytes);
-typedef void (*encoding_become_encoding_t)(PARROT_INTERP, STRING *src);
-typedef UINTVAL (*encoding_codepoints_t)(PARROT_INTERP, STRING *src);
-typedef UINTVAL (*encoding_bytes_t)(PARROT_INTERP, STRING *src);
+typedef UINTVAL (*encoding_codepoints_t)(PARROT_INTERP, ARGIN(const STRING *src));
+typedef UINTVAL (*encoding_bytes_t)(PARROT_INTERP, ARGIN(const STRING *src));
 typedef UINTVAL (*encoding_find_cclass_t)(PARROT_INTERP, STRING *s, const INTVAL *typetable, INTVAL flags, UINTVAL offset, UINTVAL count);
 typedef size_t (*encoding_hash_t)(PARROT_INTERP, const STRING *s, size_t hashval);
 
@@ -44,16 +38,10 @@
     UINTVAL max_bytes_per_codepoint;
     encoding_to_encoding_t              to_encoding;
     encoding_get_codepoint_t            get_codepoint;
-    encoding_set_codepoint_t            set_codepoint;
     encoding_get_byte_t                 get_byte;
     encoding_set_byte_t                 set_byte;
     encoding_get_codepoints_t           get_codepoints;
-    encoding_get_codepoints_inplace_t   get_codepoints_inplace;
     encoding_get_bytes_t                get_bytes;
-    encoding_get_bytes_inplace_t        get_bytes_inplace;
-    encoding_set_codepoints_t           set_codepoints;
-    encoding_set_bytes_t                set_bytes;
-    encoding_become_encoding_t          become_encoding;
     encoding_codepoints_t               codepoints;
     encoding_bytes_t                    bytes;
     encoding_iter_init_t                iter_init;
@@ -208,26 +196,14 @@
     ((src)->encoding)->max_bytes_per_codepoint
 #define ENCODING_GET_CODEPOINT(i, src, offset) \
     ((src)->encoding)->get_codepoint((i), (src), (offset))
-#define ENCODING_SET_CODEPOINT(i, src, offset, codepoint) \
-    ((src)->encoding)->set_codepoint((i), (src), (offset), (codepoint))
 #define ENCODING_GET_BYTE(i, src, offset) \
     ((src)->encoding)->get_byte((i), (src), (offset))
 #define ENCODING_SET_BYTE(i, src, offset, value) \
     ((src)->encoding)->set_byte((i), (src), (offset), (value))
 #define ENCODING_GET_CODEPOINTS(i, src, offset, count) \
     ((src)->encoding)->get_codepoints((i), (src), (offset), (count))
-#define ENCODING_GET_CODEPOINTS_INPLACE(i, src, offset, count, dest) \
-    ((src)->encoding)->get_codepoints_inplace((i), (src), (offset), (count), (dest))
 #define ENCODING_GET_BYTES(i, src, offset, count) \
     ((src)->encoding)->get_bytes((i), (src), (offset), (count))
-#define ENCODING_GET_BYTES_INPLACE(i, src, offset, count, dest) \
-    ((src)->encoding)->get_bytes_inplace((i), (src), (offset), (count), (dest))
-#define ENCODING_SET_CODEPOINTS(i, src, offset, count, newdata) \
-    ((src)->encoding)->set_codepoints((i), (src), (offset), (count), (newdata))
-#define ENCODING_SET_BYTES(i, src, offset, count, newdata) \
-    ((src)->encoding)->set_bytes((i), (src), (offset), (count), (newdata))
-#define ENCODING_BECOME_ENCODING(i, src) \
-    ((src)->encoding)->become_encoding((i), (src))
 #define ENCODING_CODEPOINTS(i, src) \
     ((src)->encoding)->codepoints((i), (src))
 #define ENCODING_BYTES(i, src) \

Modified: trunk/include/parrot/io.h
==============================================================================
--- trunk/include/parrot/io.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/include/parrot/io.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -453,14 +453,17 @@
         FUNC_MODIFIES(*filehandle)
         FUNC_MODIFIES(*buf);
 
+PARROT_WARN_UNUSED_RESULT
 size_t Parrot_io_read_buffer(PARROT_INTERP,
     ARGMOD(PMC *filehandle),
-    ARGIN(STRING **buf))
+    ARGMOD(STRING **buf))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        FUNC_MODIFIES(*filehandle);
+        FUNC_MODIFIES(*filehandle)
+        FUNC_MODIFIES(*buf);
 
+PARROT_WARN_UNUSED_RESULT
 size_t Parrot_io_readline_buffer(PARROT_INTERP,
     ARGMOD(PMC *filehandle),
     ARGOUT(STRING **buf))
@@ -646,7 +649,7 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL Parrot_io_parse_open_flags(PARROT_INTERP,
-    ARGIN_NULLOK(STRING *mode_str))
+    ARGIN_NULLOK(const STRING *mode_str))
         __attribute__nonnull__(1);
 
 PARROT_EXPORT

Modified: trunk/include/parrot/string_funcs.h
==============================================================================
--- trunk/include/parrot/string_funcs.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/include/parrot/string_funcs.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -27,48 +27,31 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-STRING * Parrot_str_append(PARROT_INTERP,
-    ARGMOD_NULLOK(STRING *a),
-    ARGIN_NULLOK(STRING *b))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*a);
-
-PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 STRING * Parrot_str_bitwise_and(PARROT_INTERP,
     ARGIN_NULLOK(const STRING *s1),
-    ARGIN_NULLOK(const STRING *s2),
-    ARGOUT_NULLOK(STRING **dest))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*dest);
+    ARGIN_NULLOK(const STRING *s2))
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 STRING * Parrot_str_bitwise_not(PARROT_INTERP,
-    ARGIN_NULLOK(const STRING *s),
-    ARGOUT_NULLOK(STRING **dest))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*dest);
+    ARGIN_NULLOK(const STRING *s))
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 STRING * Parrot_str_bitwise_or(PARROT_INTERP,
     ARGIN_NULLOK(const STRING *s1),
-    ARGIN_NULLOK(const STRING *s2),
-    ARGOUT_NULLOK(STRING **dest))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*dest);
+    ARGIN_NULLOK(const STRING *s2))
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 STRING * Parrot_str_bitwise_xor(PARROT_INTERP,
     ARGIN_NULLOK(const STRING *s1),
-    ARGIN_NULLOK(const STRING *s2),
-    ARGOUT_NULLOK(STRING **dest))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*dest);
+    ARGIN_NULLOK(const STRING *s2))
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
@@ -84,21 +67,17 @@
 PARROT_CAN_RETURN_NULL
 STRING* Parrot_str_change_charset(PARROT_INTERP,
     ARGMOD_NULLOK(STRING *src),
-    INTVAL charset_nr,
-    ARGOUT_NULLOK(STRING *dest))
+    INTVAL charset_nr)
         __attribute__nonnull__(1)
-        FUNC_MODIFIES(*src)
-        FUNC_MODIFIES(*dest);
+        FUNC_MODIFIES(*src);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 STRING* Parrot_str_change_encoding(PARROT_INTERP,
     ARGIN_NULLOK(STRING *src),
-    INTVAL encoding_nr,
-    ARGOUT_NULLOK(STRING *dest))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*dest);
+    INTVAL encoding_nr)
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
@@ -108,12 +87,6 @@
         FUNC_MODIFIES(*s);
 
 PARROT_EXPORT
-void Parrot_str_chopn_inplace(PARROT_INTERP, ARGMOD(STRING *s), INTVAL n)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL Parrot_str_compare(PARROT_INTERP,
     ARGIN_NULLOK(const STRING *s1),
@@ -130,8 +103,7 @@
 PARROT_CANNOT_RETURN_NULL
 STRING * Parrot_str_concat(PARROT_INTERP,
     ARGIN_NULLOK(STRING *a),
-    ARGIN_NULLOK(STRING *b),
-    UINTVAL Uflags)
+    ARGIN_NULLOK(STRING *b))
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
@@ -149,11 +121,6 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
-void Parrot_str_downcase_inplace(PARROT_INTERP, ARGMOD_NULLOK(STRING *s))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL Parrot_str_equal(PARROT_INTERP,
     ARGIN_NULLOK(const STRING *s1),
@@ -264,10 +231,8 @@
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
-INTVAL Parrot_str_length(PARROT_INTERP, ARGMOD(STRING *s))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*s);
+INTVAL Parrot_str_length(SHIM_INTERP, ARGIN(const STRING *s))
+        __attribute__nonnull__(2);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
@@ -286,14 +251,6 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-STRING * Parrot_str_new_COW(PARROT_INTERP, ARGMOD(STRING *s))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
@@ -332,8 +289,7 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
-void Parrot_str_pin(PARROT_INTERP, ARGMOD(STRING *s))
-        __attribute__nonnull__(1)
+void Parrot_str_pin(SHIM_INTERP, ARGMOD(STRING *s))
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*s);
 
@@ -347,42 +303,15 @@
 
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
 STRING * Parrot_str_replace(PARROT_INTERP,
     ARGIN(STRING *src),
     INTVAL offset,
     INTVAL length,
-    ARGIN(STRING *rep),
-    ARGOUT_NULLOK(STRING **d))
+    ARGIN(STRING *rep))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*d);
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING * Parrot_str_resize(PARROT_INTERP, ARGMOD(STRING *s), UINTVAL addlen)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING * Parrot_str_reuse_COW(SHIM_INTERP,
-    ARGMOD(STRING *s),
-    ARGOUT(STRING *d))
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*s)
-        FUNC_MODIFIES(*d);
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING * Parrot_str_set(PARROT_INTERP,
-    ARGIN_NULLOK(STRING *dest),
-    ARGMOD(STRING *src))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*src);
+        __attribute__nonnull__(5);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
@@ -398,11 +327,8 @@
 STRING * Parrot_str_substr(PARROT_INTERP,
     ARGIN_NULLOK(STRING *src),
     INTVAL offset,
-    INTVAL length,
-    ARGOUT_NULLOK(STRING **d),
-    int replace_dest)
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*d);
+    INTVAL length)
+        __attribute__nonnull__(1);
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
@@ -411,11 +337,6 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
-void Parrot_str_titlecase_inplace(PARROT_INTERP, ARGMOD_NULLOK(STRING *s))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
 char * Parrot_str_to_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
@@ -460,29 +381,12 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
-void Parrot_str_upcase_inplace(PARROT_INTERP, ARGMOD_NULLOK(STRING *s))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
-void Parrot_str_write_COW(PARROT_INTERP, ARGMOD(STRING *s))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*s);
-
-PARROT_EXPORT
 PARROT_PURE_FUNCTION
 PARROT_CANNOT_RETURN_NULL
 const char * Parrot_string_cstring(SHIM_INTERP, ARGIN(const STRING *str))
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_PURE_FUNCTION
-UINTVAL string_capacity(SHIM_INTERP, ARGIN(const STRING *s))
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING * string_chr(PARROT_INTERP, UINTVAL character)
@@ -546,6 +450,12 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
+STRING* Parrot_str_clone(PARROT_INTERP, ARGIN(const STRING *s))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
 STRING * Parrot_str_from_int_base(PARROT_INTERP,
     ARGOUT(char *tc),
     HUGEINTVAL num,
@@ -565,8 +475,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*tc);
 
-#define ASSERT_ARGS_Parrot_str_append __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_bitwise_and __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_bitwise_not __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -585,9 +493,6 @@
 #define ASSERT_ARGS_Parrot_str_chopn __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(s))
-#define ASSERT_ARGS_Parrot_str_chopn_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_compose __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -599,8 +504,6 @@
     , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_downcase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_str_downcase_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_equal __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_escape __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -638,16 +541,12 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(ar))
 #define ASSERT_ARGS_Parrot_str_length __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
+       PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_new __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_new_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(buffer))
-#define ASSERT_ARGS_Parrot_str_new_COW __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_new_from_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(buffer))
@@ -660,8 +559,7 @@
 #define ASSERT_ARGS_Parrot_str_not_equal __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_pin __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
+       PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_repeat __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(s))
@@ -669,23 +567,12 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src) \
     , PARROT_ASSERT_ARG(rep))
-#define ASSERT_ARGS_Parrot_str_resize __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
-#define ASSERT_ARGS_Parrot_str_reuse_COW __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(s) \
-    , PARROT_ASSERT_ARG(d))
-#define ASSERT_ARGS_Parrot_str_set __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_Parrot_str_split __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_substr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_titlecase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_str_titlecase_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_to_cstring __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_str_to_hashval __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -703,15 +590,8 @@
     , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_upcase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_str_upcase_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_str_write_COW __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_string_cstring __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(str))
-#define ASSERT_ARGS_string_capacity __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_string_chr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_string_increment __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -730,6 +610,9 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_string_to_cstring_nullable __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_Parrot_str_clone __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_Parrot_str_from_int_base __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(tc))

Modified: trunk/include/parrot/string_primitives.h
==============================================================================
--- trunk/include/parrot/string_primitives.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/include/parrot/string_primitives.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -36,12 +36,11 @@
 PARROT_EXPORT
 Parrot_UInt4 string_unescape_one(PARROT_INTERP,
     ARGMOD(UINTVAL *offset),
-    ARGMOD(STRING *string))
+    ARGIN(const STRING *string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        FUNC_MODIFIES(*offset)
-        FUNC_MODIFIES(*string);
+        FUNC_MODIFIES(*offset);
 
 #define ASSERT_ARGS_Parrot_char_digit_value __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_str_dup_remove_quotes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/lib/Parrot/Configure/Options/Test/Prepare.pm
==============================================================================
--- trunk/lib/Parrot/Configure/Options/Test/Prepare.pm	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/lib/Parrot/Configure/Options/Test/Prepare.pm	Wed Apr 21 10:06:00 2010	(r45852)
@@ -78,6 +78,8 @@
                 ? qq|$secondlevel-$number|
                 : $number;
             $steps_tests_complex{$category}{$class}{$final}++;
+
+            return;
         }
     } # END wanted()
     finddepth( \&wanted, ( $steps_dir ) );

Modified: trunk/lib/Parrot/Distribution.pm
==============================================================================
--- trunk/lib/Parrot/Distribution.pm	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/lib/Parrot/Distribution.pm	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2009, Parrot Foundation.
+# Copyright (C) 2004-2010, Parrot Foundation.
 # $Id$
 
 =head1 NAME
@@ -248,13 +248,13 @@
                 # and make a hash out of the directories
                 my %dirs =
                     map { ( ( File::Spec->splitpath($_) )[1] => 1 ) }
-                    grep { m|(?i)(?:$filter_ext)| } $self->_dist_files;
+                    grep { m/(?i)(?:$filter_ext)/ } $self->_dist_files;
 
                 # Filter out ignored directories
                 # and return the results
                 my @dirs = sort
                     map  { $self->directory_with_name($_) }
-                    grep { !m|(?:$filter_dir)| }
+                    grep { !m/(?:$filter_dir)/ }
                     keys %dirs;
                 return @dirs;
             };
@@ -293,7 +293,7 @@
                 # and return a sorted list of filenames
                 my @files = sort
                     map  { $self->file_with_name($_) }
-                    grep { m|(?i)(?:$filter_ext)| }
+                    grep { m/(?i)(?:$filter_ext)/ }
                     $self->_dist_files;
                 return @files;
             };
@@ -334,7 +334,7 @@
     # and return a sorted list of filenames
     my @files = sort
         map  { $self->file_with_name($_) }
-        grep { m|[/\\]makefiles[/\\][a-z]+\.in$| }
+        grep { m{[/\\]makefiles[/\\][a-z]+\.in$} }
         $self->_dist_files;
     return @files;
 }

Modified: trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
==============================================================================
--- trunk/lib/Parrot/Pmc2c/PMCEmitter.pm	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/lib/Parrot/Pmc2c/PMCEmitter.pm	Wed Apr 21 10:06:00 2010	(r45852)
@@ -570,7 +570,7 @@
         vt->base_type    = entry;
         vt->whoami       = string_make(interp, "$classname", @{[length($classname)]},
                                        "ascii", PObj_constant_FLAG|PObj_external_FLAG);
-        vt->provides_str = Parrot_str_append(interp, vt->provides_str,
+        vt->provides_str = Parrot_str_concat(interp, vt->provides_str,
             string_make(interp, "$provides", @{[length($provides)]}, "ascii",
             PObj_constant_FLAG|PObj_external_FLAG));
 

Modified: trunk/src/call/args.c
==============================================================================
--- trunk/src/call/args.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/call/args.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -364,9 +364,7 @@
             {
                 STRING *string_value;
                 if (constant)
-                    /* ensure that callees don't modify constant caller strings */
-                    string_value = Parrot_str_new_COW(interp,
-                            Parrot_pcc_get_string_constant(interp, ctx, raw_index));
+                    string_value = Parrot_pcc_get_string_constant(interp, ctx, raw_index);
                 else
                     string_value = CTX_REG_STR(ctx, raw_index);
 
@@ -456,10 +454,8 @@
         break;
       case PARROT_ARG_STRING:
         if (constant)
-            /* ensure that callees don't modify constant caller strings */
             VTABLE_set_string_keyed_str(interp, call_object, name,
-                        Parrot_str_new_COW(interp,
-                                Parrot_pcc_get_string_constant(interp, ctx, raw_index)));
+                    Parrot_pcc_get_string_constant(interp, ctx, raw_index));
         else
             VTABLE_set_string_keyed_str(interp, call_object, name,
                         CTX_REG_STR(ctx, raw_index));

Modified: trunk/src/dynext.c
==============================================================================
--- trunk/src/dynext.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/dynext.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -294,7 +294,7 @@
 
         for (i = 0; i < n; ++i) {
             ext = VTABLE_get_string_keyed_int(interp, share_ext, i);
-            full_name = Parrot_str_concat(interp, wo_ext, ext, 0);
+            full_name = Parrot_str_concat(interp, wo_ext, ext);
             path = Parrot_locate_runtime_file_str(interp, full_name,
                     PARROT_RUNTIME_FT_DYNEXT);
             if (path) {
@@ -350,7 +350,7 @@
     /* And on cygwin replace a leading "lib" by "cyg". */
 #ifdef __CYGWIN__
     if (!STRING_IS_EMPTY(lib) && memcmp(lib->strstart, "lib", 3) == 0) {
-        path = Parrot_str_append(interp, CONST_STRING(interp, "cyg"),
+        path = Parrot_str_concat(interp, CONST_STRING(interp, "cyg"),
             Parrot_str_substr(interp, lib, 3, lib->strlen - 3, NULL, 0));
 
         *handle = dlopen_string(interp, flags, path);

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/hash.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -183,7 +183,8 @@
         return 1;
 
     /* COWed strings */
-    if (Buffer_bufstart(s1) == Buffer_bufstart(s2) && s1->bufused == s2->bufused)
+    if (Buffer_bufstart(s1) == Buffer_bufstart(s2)
+    &&  s1->bufused == s2->bufused)
         return 0;
 
     return CHARSET_COMPARE(interp, s1, s2);
@@ -1323,13 +1324,14 @@
     /* When the hash is constant, check that the key and value are also
      * constant. */
     if (!PMC_IS_NULL(hash->container)
-            && PObj_constant_TEST(hash->container)) {
+    &&   PObj_constant_TEST(hash->container)) {
         if (hash->key_type == Hash_key_type_STRING
-                && !PObj_constant_TEST((PObj *)key))
+        && !PObj_constant_TEST((PObj *)key))
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                 "Used non-constant key in constant hash.");
-        if (((hash->entry_type == enum_type_PMC) || (hash->entry_type == enum_type_STRING))
-                && !PObj_constant_TEST((PObj *)value))
+            if (((hash->entry_type == enum_type_PMC)
+            ||   (hash->entry_type == enum_type_STRING))
+            &&   !PObj_constant_TEST((PObj *)value))
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                 "Used non-constant value in constant hash.");
     }
@@ -1434,7 +1436,7 @@
             break;
 
           case enum_type_STRING:
-            valtmp = (void *)Parrot_str_copy(interp, (STRING *)b->value);
+            valtmp = b->value;
             break;
 
           case enum_type_PMC:
@@ -1450,9 +1452,8 @@
                     "hash corruption: type = %d\n", hash->entry_type);
         };
 
-        if (key){
+        if (key)
             parrot_hash_put(interp, dest, key, valtmp);
-        }
     }
 }
 

Modified: trunk/src/hll.c
==============================================================================
--- trunk/src/hll.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/hll.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -521,11 +521,11 @@
         if (PMC_IS_NULL(ns_hash) ||
                 ns_hash->vtable->base_type == enum_class_Undef)
         {
-            STRING * const hll_name = Parrot_get_HLL_name(interp, hll_id);
+            STRING * hll_name = Parrot_get_HLL_name(interp, hll_id);
             if (!hll_name)
                 continue;
 
-            Parrot_str_downcase_inplace(interp, hll_name);
+            hll_name = Parrot_str_downcase(interp, hll_name);
 
             /* XXX as in Parrot_register_HLL() this needs to be fixed to use
              * the correct type of namespace. It's relatively easy to do that

Modified: trunk/src/io/api.c
==============================================================================
--- trunk/src/io/api.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/io/api.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -366,7 +366,7 @@
                 "Cannot read from a closed filehandle");
 
         if (length == 0)
-            result = Parrot_str_copy(interp, string_orig);
+            result = string_orig;
         else {
             INTVAL read_length = length;
             const INTVAL orig_length = Parrot_str_byte_length(interp, string_orig);
@@ -377,8 +377,7 @@
             if (offset + read_length > orig_length)
                 read_length = orig_length - offset;
 
-            result = Parrot_str_substr(interp, string_orig, offset,
-                    read_length, NULL, 0);
+            result = Parrot_str_substr(interp, string_orig, offset, read_length);
             SETATTR_StringHandle_read_offset(interp, pmc, offset + read_length);
         }
     }
@@ -436,8 +435,7 @@
         else
             read_length = newline_pos - offset + 1; /* +1 to include the newline */
 
-        result = Parrot_str_substr(interp, result, offset,
-                read_length, NULL, 0);
+        result = Parrot_str_substr(interp, result, offset, read_length);
         SETATTR_StringHandle_read_offset(interp, pmc, newline_pos + 1);
     }
     else

Modified: trunk/src/io/buffer.c
==============================================================================
--- trunk/src/io/buffer.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/io/buffer.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -266,9 +266,10 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 size_t
 Parrot_io_read_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle),
-              ARGIN(STRING **buf))
+              ARGMOD(STRING **buf))
 {
     ASSERT_ARGS(Parrot_io_read_buffer)
     unsigned char *out_buf, *buffer_start, *buffer_next, *buffer_end;
@@ -449,6 +450,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 size_t
 Parrot_io_readline_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle), ARGOUT(STRING **buf))
 {

Modified: trunk/src/io/filehandle.c
==============================================================================
--- trunk/src/io/filehandle.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/io/filehandle.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -27,7 +27,8 @@
 
 =over 4
 
-=item C<INTVAL Parrot_io_parse_open_flags(PARROT_INTERP, STRING *mode_str)>
+=item C<INTVAL Parrot_io_parse_open_flags(PARROT_INTERP, const STRING
+*mode_str)>
 
 Parses a Parrot string for file open mode flags (C<r> for read, C<w> for write,
 C<a> for append, and C<p> for pipe) and returns the combined generic bit flags.
@@ -39,7 +40,7 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN_NULLOK(STRING *mode_str))
+Parrot_io_parse_open_flags(PARROT_INTERP, ARGIN_NULLOK(const STRING *mode_str))
 {
     ASSERT_ARGS(Parrot_io_parse_open_flags)
     INTVAL i, mode_len;

Modified: trunk/src/io/utf8.c
==============================================================================
--- trunk/src/io/utf8.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/io/utf8.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -83,7 +83,10 @@
                 UNUSED(read);
 
                 s->strlen    = iter.charpos;
-                s            = Parrot_str_append(interp, s, s2);
+                s            = Parrot_str_concat(interp, s, s2);
+                /* String is updated. Poke into iterator to replace old string */
+                iter.str     = s;
+                *buf         = s;
                 len         += len2 + 1;
 
                 /* check last char */
@@ -116,8 +119,7 @@
     if (s->encoding == Parrot_utf8_encoding_ptr)
         return Parrot_io_write_buffer(interp, filehandle, s);
 
-    dest = Parrot_utf8_encoding_ptr->to_encoding(interp, s,
-            Parrot_gc_new_string_header(interp, 0));
+    dest = Parrot_utf8_encoding_ptr->to_encoding(interp, s);
     return Parrot_io_write_buffer(interp, filehandle, dest);
 }
 

Modified: trunk/src/io/win32.c
==============================================================================
--- trunk/src/io/win32.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/io/win32.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -660,8 +660,8 @@
     if (comspec == NULL)
         comspec = "cmd";
     auxcomm = Parrot_str_new(interp, comspec, 0);
-    auxcomm = Parrot_str_append(interp, auxcomm, Parrot_str_new(interp, " /c ", 0));
-    auxcomm = Parrot_str_append(interp, auxcomm, command);
+    auxcomm = Parrot_str_concat(interp, auxcomm, Parrot_str_new(interp, " /c ", 0));
+    auxcomm = Parrot_str_concat(interp, auxcomm, command);
     cmd = Parrot_str_to_cstring(interp, auxcomm);
     start.cb = sizeof start;
     GetStartupInfo(&start);

Modified: trunk/src/key.c
==============================================================================
--- trunk/src/key.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/key.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -444,8 +444,6 @@
         {
             STRING *s;
             GETATTR_Key_str_key(interp, key, s);
-            if (s)
-                s = Parrot_str_new_COW(interp, s);
             return s;
         }
       case KEY_string_FLAG | KEY_register_FLAG:
@@ -652,65 +650,65 @@
         switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
           case KEY_integer_FLAG:
             GETATTR_Key_int_key(interp, key, int_key);
-            value = Parrot_str_append(interp, value,
-                    Parrot_str_from_int(interp, int_key));
+            value = Parrot_str_concat(interp, value,
+                        Parrot_str_from_int(interp, int_key));
             break;
           case KEY_number_FLAG:
             GETATTR_Key_int_key(interp, key, int_key);
-            value = Parrot_str_append(interp, value,
-                    Parrot_str_from_num(interp, (FLOATVAL)int_key));
+            value = Parrot_str_concat(interp, value,
+                        Parrot_str_from_num(interp, (FLOATVAL)int_key));
             break;
           case KEY_string_FLAG:
             GETATTR_Key_str_key(interp, key, str_key);
-            value = Parrot_str_append(interp, value, quote);
-            value = Parrot_str_append(interp, value, str_key);
-            value = Parrot_str_append(interp, value, quote);
+            value = Parrot_str_concat(interp, value, quote);
+            value = Parrot_str_concat(interp, value, str_key);
+            value = Parrot_str_concat(interp, value, quote);
             break;
           case KEY_pmc_FLAG:
-            value = Parrot_str_append(interp, value,
-                    VTABLE_get_string(interp, key));
+            value = Parrot_str_concat(interp, value,
+                        VTABLE_get_string(interp, key));
             break;
           case KEY_integer_FLAG | KEY_register_FLAG:
             GETATTR_Key_int_key(interp, key, int_key);
-            value = Parrot_str_append(interp, value,
+            value = Parrot_str_concat(interp, value,
                         Parrot_str_from_int(interp,
                             REG_INT(interp, int_key)));
             break;
           case KEY_number_FLAG | KEY_register_FLAG:
             GETATTR_Key_int_key(interp, key, int_key);
-            value = Parrot_str_append(interp, value,
+            value = Parrot_str_concat(interp, value,
                         Parrot_str_from_num(interp,
                             REG_NUM(interp, int_key)));
             break;
           case KEY_string_FLAG | KEY_register_FLAG:
-            value = Parrot_str_append(interp, value, quote);
+            value = Parrot_str_concat(interp, value, quote);
             GETATTR_Key_int_key(interp, key, int_key);
-            value = Parrot_str_append(interp, value,
+            value = Parrot_str_concat(interp, value,
                     REG_STR(interp, int_key));
-            value = Parrot_str_append(interp, value, quote);
+            value = Parrot_str_concat(interp, value, quote);
             break;
           case KEY_pmc_FLAG | KEY_register_FLAG:
             {
                 PMC *reg;
                 GETATTR_Key_int_key(interp, key, int_key);
                 reg = REG_PMC(interp, int_key);
-                value           = Parrot_str_append(interp, value,
-                                    VTABLE_get_string(interp, reg));
+                value = Parrot_str_concat(interp, value,
+                            VTABLE_get_string(interp, reg));
             }
             break;
           default:
-            value = Parrot_str_append(interp, value, CONST_STRING(interp, "Key type unknown"));
+            value = Parrot_str_concat(interp, value, CONST_STRING(interp, "Key type unknown"));
             break;
         }
 
         GETATTR_Key_next_key(interp, key, next_key);
         if (next_key)
-            value = Parrot_str_append(interp, value, semicolon);
+            value = Parrot_str_concat(interp, value, semicolon);
 
         GETATTR_Key_next_key(interp, key, key);
     }
 
-    value = Parrot_str_append(interp, value, Parrot_str_new(interp, " ]", 2));
+    value = Parrot_str_concat(interp, value, Parrot_str_new(interp, " ]", 2));
     return value;
 }
 

Modified: trunk/src/library.c
==============================================================================
--- trunk/src/library.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/library.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -181,7 +181,7 @@
 
         versionlib = VTABLE_get_string_keyed_str(interp, config_hash, libkey);
         entry      = VTABLE_get_string_keyed_str(interp, config_hash, verkey);
-        versionlib = Parrot_str_append(interp, versionlib, entry);
+        versionlib = Parrot_str_concat(interp, versionlib, entry);
 
         if (!VTABLE_get_integer_keyed_str(interp, config_hash, installed))
             builddir = VTABLE_get_string_keyed_str(interp,
@@ -202,15 +202,15 @@
         }
     }
     if (!STRING_IS_NULL(builddir)) {
-        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/"), 0);
+        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/"));
         VTABLE_push_string(interp, paths, entry);
-        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/include/"), 0);
+        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/include/"));
         VTABLE_push_string(interp, paths, entry);
     }
     entry = CONST_STRING(interp, "./");
     VTABLE_push_string(interp, paths, entry);
     if (!STRING_IS_NULL(versionlib)) {
-        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/include/"), 0);
+        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/include/"));
         VTABLE_push_string(interp, paths, entry);
     }
 
@@ -227,13 +227,13 @@
         }
     }
     if (!STRING_IS_NULL(builddir)) {
-        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/library/"), 0);
+        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/library/"));
         VTABLE_push_string(interp, paths, entry);
     }
     entry = CONST_STRING(interp, "./");
     VTABLE_push_string(interp, paths, entry);
     if (!STRING_IS_NULL(versionlib)) {
-        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/library/"), 0);
+        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/library/"));
         VTABLE_push_string(interp, paths, entry);
     }
 
@@ -242,13 +242,13 @@
     VTABLE_set_pmc_keyed_int(interp, lib_paths,
             PARROT_LIB_PATH_LANG, paths);
     if (!STRING_IS_NULL(builddir)) {
-        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/languages/"), 0);
+        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/languages/"));
         VTABLE_push_string(interp, paths, entry);
     }
     entry = CONST_STRING(interp, "./");
     VTABLE_push_string(interp, paths, entry);
     if (!STRING_IS_NULL(versionlib)) {
-        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/languages/"), 0);
+        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/languages/"));
         VTABLE_push_string(interp, paths, entry);
     }
 
@@ -257,13 +257,13 @@
     VTABLE_set_pmc_keyed_int(interp, lib_paths,
             PARROT_LIB_PATH_DYNEXT, paths);
     if (!STRING_IS_NULL(builddir)) {
-        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/dynext/"), 0);
+        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/dynext/"));
         VTABLE_push_string(interp, paths, entry);
     }
     entry = CONST_STRING(interp, "dynext/");
     VTABLE_push_string(interp, paths, entry);
     if (!STRING_IS_NULL(versionlib)) {
-        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/dynext/"), 0);
+        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/dynext/"));
         VTABLE_push_string(interp, paths, entry);
     }
 
@@ -419,7 +419,7 @@
 
     STRING * const nul = string_chr(interp, '\0');
 
-    path = Parrot_str_append(interp, path, nul);
+    path = Parrot_str_concat(interp, path, nul);
     path->bufused--;
     path->strlen--;
 
@@ -454,7 +454,7 @@
     /* make sure the path has a trailing slash before appending the file */
     if (Parrot_str_indexed(interp, path , path->strlen - 1)
          != Parrot_str_indexed(interp, path_separator_string, 0))
-        path = Parrot_str_append(interp, path , path_separator_string);
+        path = Parrot_str_concat(interp, path , path_separator_string);
 
     return path;
 }
@@ -479,7 +479,7 @@
 {
     ASSERT_ARGS(path_append)
     l_path = path_guarantee_trailing_separator(interp, l_path);
-    l_path = Parrot_str_append(interp, l_path, r_path);
+    l_path = Parrot_str_concat(interp, l_path, r_path);
 
     return l_path;
 }
@@ -505,9 +505,9 @@
     ASSERT_ARGS(path_concat)
     STRING* join;
 
-    join = Parrot_str_copy(interp, l_path);
+    join = l_path;
     join = path_guarantee_trailing_separator(interp, join);
-    join = Parrot_str_append(interp, join, r_path);
+    join = Parrot_str_concat(interp, join, r_path);
 
     return join;
 }
@@ -532,9 +532,7 @@
     ASSERT_ARGS(try_load_path)
     STRING *final;
 
-    final = Parrot_str_copy(interp, path);
-
-    final = path_finalize(interp, final);
+    final = path_finalize(interp, path);
 
     if (Parrot_stat_info_intval(interp, final, STAT_EXISTS)) {
         return final;
@@ -566,7 +564,7 @@
     STRING * const pir_extension      = CONST_STRING(interp, ".pir");
     STRING * const pasm_extension     = CONST_STRING(interp, ".pasm");
 
-    test_path = Parrot_str_copy(interp, path);
+    test_path = path;
 
     /* First try the path as given. */
     result = try_load_path(interp, test_path);
@@ -582,11 +580,11 @@
 
     if (!STRING_IS_NULL(test_path)) {
         if (Parrot_str_byte_length(interp, test_path) > 4) {
-            STRING *orig_ext = Parrot_str_substr(interp, test_path, -4, 4, NULL, 0);
+            STRING *orig_ext = Parrot_str_substr(interp, test_path, -4, 4);
             /* First try substituting .pbc for the .pir extension */
             if (Parrot_str_equal(interp, orig_ext, pir_extension)) {
                 STRING * const without_ext = Parrot_str_chopn(interp, test_path, 4);
-                test_path = Parrot_str_append(interp, without_ext, bytecode_extension);
+                test_path = Parrot_str_concat(interp, without_ext, bytecode_extension);
                 result = try_load_path(interp, test_path);
                 if (result)
                     return result;
@@ -594,12 +592,12 @@
             /* Next try substituting .pir, then .pasm for the .pbc extension */
             else if (Parrot_str_equal(interp, orig_ext, bytecode_extension)) {
                 STRING * const without_ext = Parrot_str_chopn(interp, test_path, 4);
-                test_path = Parrot_str_append(interp, without_ext, pir_extension);
+                test_path = Parrot_str_concat(interp, without_ext, pir_extension);
                 result = try_load_path(interp, test_path);
                 if (result)
                     return result;
 
-                test_path = Parrot_str_append(interp, without_ext, pasm_extension);
+                test_path = Parrot_str_concat(interp, without_ext, pasm_extension);
                 result = try_load_path(interp, test_path);
                 if (result)
                     return result;
@@ -609,10 +607,10 @@
 
         /* Finally, try substituting .pbc for the .pasm extension. */
         if (Parrot_str_byte_length(interp, test_path) > 5) {
-            STRING * const orig_ext = Parrot_str_substr(interp, test_path, -5, 5, NULL, 0);
+            STRING * const orig_ext = Parrot_str_substr(interp, test_path, -5, 5);
             if (Parrot_str_equal(interp, orig_ext, pasm_extension)) {
                 STRING * const without_ext = Parrot_str_chopn(interp, test_path, 5);
-                test_path = Parrot_str_append(interp, without_ext, bytecode_extension);
+                test_path = Parrot_str_concat(interp, without_ext, bytecode_extension);
                 result = try_load_path(interp, test_path);
                 if (result)
                     return result;
@@ -717,8 +715,7 @@
         STRING * const path = VTABLE_get_string_keyed_int(interp, paths, i);
         STRING *found_name;
 
-        full_name = Parrot_str_copy(interp, path);
-        full_name = path_append(interp, full_name, file);
+        full_name = path_append(interp, path, file);
 
         found_name =
             (type & PARROT_RUNTIME_FT_DYNEXT)
@@ -917,23 +914,22 @@
     ++pos_dot;
     ++pos_sl;
     if (pos_sl && pos_dot) {
-        stem = Parrot_str_substr(interp, in, pos_sl, pos_dot - pos_sl - 1,
-                NULL, 0);
-        *wo_ext = Parrot_str_substr(interp, in, 0, pos_dot - 1, NULL, 0);
-        *ext = Parrot_str_substr(interp, in, pos_dot, len - pos_dot, NULL, 0);
+        stem = Parrot_str_substr(interp, in, pos_sl, pos_dot - pos_sl - 1);
+        *wo_ext = Parrot_str_substr(interp, in, 0, pos_dot - 1);
+        *ext = Parrot_str_substr(interp, in, pos_dot, len - pos_dot);
     }
     else if (pos_dot) {
-        stem = Parrot_str_substr(interp, in, 0, pos_dot - 1, NULL, 0);
+        stem = Parrot_str_substr(interp, in, 0, pos_dot - 1);
         *wo_ext = stem;
-        *ext = Parrot_str_substr(interp, in, pos_dot, len - pos_dot, NULL, 0);
+        *ext = Parrot_str_substr(interp, in, pos_dot, len - pos_dot);
     }
     else if (pos_sl) {
-        stem = Parrot_str_substr(interp, in, pos_sl, len - pos_sl, NULL, 0);
-        *wo_ext = Parrot_str_copy(interp, in);
+        stem = Parrot_str_substr(interp, in, pos_sl, len - pos_sl);
+        *wo_ext = in;
         *ext = NULL;
     }
     else {
-        stem = Parrot_str_copy(interp, in);
+        stem = in;
         *wo_ext = stem;
         *ext = NULL;
     }

Modified: trunk/src/ops/bit.ops
==============================================================================
--- trunk/src/ops/bit.ops	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/ops/bit.ops	Wed Apr 21 10:06:00 2010	(r45852)
@@ -109,37 +109,37 @@
 
 =cut
 
-inline op bands(inout STR, in STR) :base_core {
-    Parrot_str_bitwise_and(interp, $1, $2, &$1);
+inline op bands(inout STR, in STR) :base_core :deprecated {
+    $1 = Parrot_str_bitwise_and(interp, $1, $2);
 }
 
 inline op bands(invar PMC, in STR) :base_core {
     STRING * const a = VTABLE_get_string(interp, $1);
-    STRING * const b = Parrot_str_bitwise_and(interp, a, $2, NULL);
+    STRING * const b = Parrot_str_bitwise_and(interp, a, $2);
     VTABLE_set_string_native(interp, $1, b);
 }
 
 inline op bands(invar PMC, invar PMC) :base_core {
     STRING * a = VTABLE_get_string(interp, $1);
     STRING * const b = VTABLE_get_string(interp, $2);
-    a = Parrot_str_bitwise_and(interp, a, b, NULL);
+    a = Parrot_str_bitwise_and(interp, a, b);
     VTABLE_set_string_native(interp, $1, a);
 }
 
 inline op bands(out STR, in STR, in STR) :base_core {
-    $1 = Parrot_str_bitwise_and(interp, $2, $3, NULL);
+    $1 = Parrot_str_bitwise_and(interp, $2, $3);
 }
 
 inline op bands(invar PMC, invar PMC, in STR) :base_core {
     STRING * const a = VTABLE_get_string(interp, $2);
-    STRING * const b = Parrot_str_bitwise_and(interp, a, $3, NULL);
+    STRING * const b = Parrot_str_bitwise_and(interp, a, $3);
     VTABLE_set_string_native(interp, $1, b);
 }
 
 inline op bands(invar PMC, invar PMC, invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $2);
     STRING * const b = VTABLE_get_string(interp, $3);
-    STRING * const c = Parrot_str_bitwise_and(interp, a, b, NULL);
+    STRING * const c = Parrot_str_bitwise_and(interp, a, b);
     VTABLE_set_string_native(interp, $1, c);
 }
 
@@ -187,23 +187,23 @@
 
 =cut
 
-inline op bnots(inout STR) :base_core {
-    Parrot_str_bitwise_not(interp, $1, &$1);
+inline op bnots(inout STR) :base_core :deprecated {
+    $1 = Parrot_str_bitwise_not(interp, $1);
 }
 
 inline op bnots(out STR, in STR) :base_core {
-    Parrot_str_bitwise_not(interp, $2, &$1);
+    $1 = Parrot_str_bitwise_not(interp, $2);
 }
 
 inline op bnots(invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $1);
-    STRING * const b = Parrot_str_bitwise_not(interp, a, NULL);
+    STRING * const b = Parrot_str_bitwise_not(interp, a);
     VTABLE_set_string_native(interp, $1, b);
 }
 
 inline op bnots(out PMC, invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $2);
-    STRING * const b = Parrot_str_bitwise_not(interp, a, NULL);
+    STRING * const b = Parrot_str_bitwise_not(interp, a);
     VTABLE_set_string_native(interp, $1, b);
 }
 
@@ -279,37 +279,37 @@
 
 =cut
 
-inline op bors(inout STR, in STR) :base_core {
-    Parrot_str_bitwise_or(interp, $1, $2, &$1);
+inline op bors(inout STR, in STR) :base_core :deprecated {
+    $1 = Parrot_str_bitwise_or(interp, $1, $2);
 }
 
 inline op bors(invar PMC, in STR) :base_core {
     STRING * const a = VTABLE_get_string(interp, $1);
-    STRING * const b = Parrot_str_bitwise_or(interp, a, $2, NULL);
+    STRING * const b = Parrot_str_bitwise_or(interp, a, $2);
     VTABLE_set_string_native(interp, $1, b);
 }
 
 inline op bors(invar PMC, invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $1);
     STRING * const b = VTABLE_get_string(interp, $2);
-    STRING * const c = Parrot_str_bitwise_or(interp, a, b, NULL);
+    STRING * const c = Parrot_str_bitwise_or(interp, a, b);
     VTABLE_set_string_native(interp, $1, c);
 }
 
 inline op bors(out STR, in STR, in STR) :base_core {
-    $1 = Parrot_str_bitwise_or(interp, $2, $3, NULL);
+    $1 = Parrot_str_bitwise_or(interp, $2, $3);
 }
 
 inline op bors(invar PMC, invar PMC, in STR) :base_core {
     STRING * const b = VTABLE_get_string(interp, $2);
-    STRING * const c = Parrot_str_bitwise_or(interp, b, $3, NULL);
+    STRING * const c = Parrot_str_bitwise_or(interp, b, $3);
     VTABLE_set_string_native(interp, $1, c);
 }
 
 inline op bors(invar PMC, invar PMC, invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $2);
     STRING * const b = VTABLE_get_string(interp, $3);
-    STRING * const c = Parrot_str_bitwise_or(interp, a, b, NULL);
+    STRING * const c = Parrot_str_bitwise_or(interp, a, b);
     VTABLE_set_string_native(interp, $1, c);
 }
 
@@ -579,37 +579,37 @@
 
 =cut
 
-inline op bxors(inout STR, in STR) :base_core {
-    Parrot_str_bitwise_xor(interp, $1, $2, &$1);
+inline op bxors(inout STR, in STR) :base_core :deprecated {
+    $1 = Parrot_str_bitwise_xor(interp, $1, $2);
 }
 
 inline op bxors(invar PMC, in STR) :base_core {
     STRING * const a = VTABLE_get_string(interp, $1);
-    STRING * const b = Parrot_str_bitwise_xor(interp, a, $2, NULL);
+    STRING * const b = Parrot_str_bitwise_xor(interp, a, $2);
     VTABLE_set_string_native(interp, $1, b);
 }
 
 inline op bxors(invar PMC, invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $1);
     STRING * const b = VTABLE_get_string(interp, $2);
-    STRING * const c = Parrot_str_bitwise_xor(interp, a, b, NULL);
+    STRING * const c = Parrot_str_bitwise_xor(interp, a, b);
     VTABLE_set_string_native(interp, $1, c);
 }
 
 inline op bxors(out STR, in STR, in STR) :base_core {
-    $1 = Parrot_str_bitwise_xor(interp, $2, $3, NULL);
+    $1 = Parrot_str_bitwise_xor(interp, $2, $3);
 }
 
 inline op bxors(invar PMC, invar PMC, in STR) :base_core {
     STRING * const a = VTABLE_get_string(interp, $2);
-    STRING * const b = Parrot_str_bitwise_xor(interp, a, $3, NULL);
+    STRING * const b = Parrot_str_bitwise_xor(interp, a, $3);
     VTABLE_set_string_native(interp, $1, b);
 }
 
 inline op bxors(invar PMC, invar PMC, invar PMC) :base_core {
     STRING * const a = VTABLE_get_string(interp, $2);
     STRING * const b = VTABLE_get_string(interp, $3);
-    STRING * const c = Parrot_str_bitwise_xor(interp, a, b, NULL);
+    STRING * const c = Parrot_str_bitwise_xor(interp, a, b);
     VTABLE_set_string_native(interp, $1, c);
 }
 

Modified: trunk/src/ops/ops.num
==============================================================================
--- trunk/src/ops/ops.num	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/ops/ops.num	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1087,193 +1087,209 @@
 substr_s_p_ic_i                1063
 substr_s_p_i_ic                1064
 substr_s_p_ic_ic               1065
-index_i_s_s                    1066
-index_i_sc_s                   1067
-index_i_s_sc                   1068
-index_i_sc_sc                  1069
-index_i_s_s_i                  1070
-index_i_sc_s_i                 1071
-index_i_s_sc_i                 1072
-index_i_sc_sc_i                1073
-index_i_s_s_ic                 1074
-index_i_sc_s_ic                1075
-index_i_s_sc_ic                1076
-index_i_sc_sc_ic               1077
-sprintf_s_s_p                  1078
-sprintf_s_sc_p                 1079
-sprintf_p_p_p                  1080
-new_s                          1081
-new_s_i                        1082
-new_s_ic                       1083
-stringinfo_i_s_i               1084
-stringinfo_i_sc_i              1085
-stringinfo_i_s_ic              1086
-stringinfo_i_sc_ic             1087
-upcase_s_s                     1088
-upcase_s_sc                    1089
-upcase_s                       1090
-downcase_s_s                   1091
-downcase_s_sc                  1092
-downcase_s                     1093
-titlecase_s_s                  1094
-titlecase_s_sc                 1095
-titlecase_s                    1096
-join_s_s_p                     1097
-join_s_sc_p                    1098
-split_p_s_s                    1099
-split_p_sc_s                   1100
-split_p_s_sc                   1101
-split_p_sc_sc                  1102
-charset_i_s                    1103
-charset_i_sc                   1104
-charsetname_s_i                1105
-charsetname_s_ic               1106
-find_charset_i_s               1107
-find_charset_i_sc              1108
-trans_charset_s_i              1109
-trans_charset_s_ic             1110
-trans_charset_s_s_i            1111
-trans_charset_s_sc_i           1112
-trans_charset_s_s_ic           1113
-trans_charset_s_sc_ic          1114
-encoding_i_s                   1115
-encoding_i_sc                  1116
-encodingname_s_i               1117
-encodingname_s_ic              1118
-find_encoding_i_s              1119
-find_encoding_i_sc             1120
-trans_encoding_s_i             1121
-trans_encoding_s_ic            1122
-trans_encoding_s_s_i           1123
-trans_encoding_s_sc_i          1124
-trans_encoding_s_s_ic          1125
-trans_encoding_s_sc_ic         1126
-is_cclass_i_i_s_i              1127
-is_cclass_i_ic_s_i             1128
-is_cclass_i_i_sc_i             1129
-is_cclass_i_ic_sc_i            1130
-is_cclass_i_i_s_ic             1131
-is_cclass_i_ic_s_ic            1132
-is_cclass_i_i_sc_ic            1133
-is_cclass_i_ic_sc_ic           1134
-find_cclass_i_i_s_i_i          1135
-find_cclass_i_ic_s_i_i         1136
-find_cclass_i_i_sc_i_i         1137
-find_cclass_i_ic_sc_i_i        1138
-find_cclass_i_i_s_ic_i         1139
-find_cclass_i_ic_s_ic_i        1140
-find_cclass_i_i_sc_ic_i        1141
-find_cclass_i_ic_sc_ic_i       1142
-find_cclass_i_i_s_i_ic         1143
-find_cclass_i_ic_s_i_ic        1144
-find_cclass_i_i_sc_i_ic        1145
-find_cclass_i_ic_sc_i_ic       1146
-find_cclass_i_i_s_ic_ic        1147
-find_cclass_i_ic_s_ic_ic       1148
-find_cclass_i_i_sc_ic_ic       1149
-find_cclass_i_ic_sc_ic_ic      1150
-find_not_cclass_i_i_s_i_i      1151
-find_not_cclass_i_ic_s_i_i     1152
-find_not_cclass_i_i_sc_i_i     1153
-find_not_cclass_i_ic_sc_i_i    1154
-find_not_cclass_i_i_s_ic_i     1155
-find_not_cclass_i_ic_s_ic_i    1156
-find_not_cclass_i_i_sc_ic_i    1157
-find_not_cclass_i_ic_sc_ic_i   1158
-find_not_cclass_i_i_s_i_ic     1159
-find_not_cclass_i_ic_s_i_ic    1160
-find_not_cclass_i_i_sc_i_ic    1161
-find_not_cclass_i_ic_sc_i_ic   1162
-find_not_cclass_i_i_s_ic_ic    1163
-find_not_cclass_i_ic_s_ic_ic   1164
-find_not_cclass_i_i_sc_ic_ic   1165
-find_not_cclass_i_ic_sc_ic_ic  1166
-escape_s_s                     1167
-compose_s_s                    1168
-compose_s_sc                   1169
-spawnw_i_s                     1170
-spawnw_i_sc                    1171
-spawnw_i_p                     1172
-err_i                          1173
-err_s                          1174
-err_s_i                        1175
-err_s_ic                       1176
-time_i                         1177
-time_n                         1178
-gmtime_s_i                     1179
-gmtime_s_ic                    1180
-localtime_s_i                  1181
-localtime_s_ic                 1182
-decodetime_p_i                 1183
-decodetime_p_ic                1184
-decodelocaltime_p_i            1185
-decodelocaltime_p_ic           1186
-sysinfo_s_i                    1187
-sysinfo_s_ic                   1188
-sysinfo_i_i                    1189
-sysinfo_i_ic                   1190
-sleep_i                        1191
-sleep_ic                       1192
-sleep_n                        1193
-sleep_nc                       1194
-sizeof_i_i                     1195
-sizeof_i_ic                    1196
-store_lex_s_p                  1197
-store_lex_sc_p                 1198
-store_dynamic_lex_s_p          1199
-store_dynamic_lex_sc_p         1200
-find_lex_p_s                   1201
-find_lex_p_sc                  1202
-find_dynamic_lex_p_s           1203
-find_dynamic_lex_p_sc          1204
-find_caller_lex_p_s            1205
-find_caller_lex_p_sc           1206
-get_namespace_p                1207
-get_namespace_p_p              1208
-get_namespace_p_pc             1209
-get_hll_namespace_p            1210
-get_hll_namespace_p_p          1211
-get_hll_namespace_p_pc         1212
-get_root_namespace_p           1213
-get_root_namespace_p_p         1214
-get_root_namespace_p_pc        1215
-get_global_p_s                 1216
-get_global_p_sc                1217
-get_global_p_p_s               1218
-get_global_p_pc_s              1219
-get_global_p_p_sc              1220
-get_global_p_pc_sc             1221
-get_hll_global_p_s             1222
-get_hll_global_p_sc            1223
-get_hll_global_p_p_s           1224
-get_hll_global_p_pc_s          1225
-get_hll_global_p_p_sc          1226
-get_hll_global_p_pc_sc         1227
-get_root_global_p_s            1228
-get_root_global_p_sc           1229
-get_root_global_p_p_s          1230
-get_root_global_p_pc_s         1231
-get_root_global_p_p_sc         1232
-get_root_global_p_pc_sc        1233
-set_global_s_p                 1234
-set_global_sc_p                1235
-set_global_p_s_p               1236
-set_global_pc_s_p              1237
-set_global_p_sc_p              1238
-set_global_pc_sc_p             1239
-set_hll_global_s_p             1240
-set_hll_global_sc_p            1241
-set_hll_global_p_s_p           1242
-set_hll_global_pc_s_p          1243
-set_hll_global_p_sc_p          1244
-set_hll_global_pc_sc_p         1245
-set_root_global_s_p            1246
-set_root_global_sc_p           1247
-set_root_global_p_s_p          1248
-set_root_global_pc_s_p         1249
-set_root_global_p_sc_p         1250
-set_root_global_pc_sc_p        1251
-find_name_p_s                  1252
-find_name_p_sc                 1253
-find_sub_not_null_p_s          1254
-find_sub_not_null_p_sc         1255
+replace_s_s_i_i_s              1066
+replace_s_sc_i_i_s             1067
+replace_s_s_ic_i_s             1068
+replace_s_sc_ic_i_s            1069
+replace_s_s_i_ic_s             1070
+replace_s_sc_i_ic_s            1071
+replace_s_s_ic_ic_s            1072
+replace_s_sc_ic_ic_s           1073
+replace_s_s_i_i_sc             1074
+replace_s_sc_i_i_sc            1075
+replace_s_s_ic_i_sc            1076
+replace_s_sc_ic_i_sc           1077
+replace_s_s_i_ic_sc            1078
+replace_s_sc_i_ic_sc           1079
+replace_s_s_ic_ic_sc           1080
+replace_s_sc_ic_ic_sc          1081
+index_i_s_s                    1082
+index_i_sc_s                   1083
+index_i_s_sc                   1084
+index_i_sc_sc                  1085
+index_i_s_s_i                  1086
+index_i_sc_s_i                 1087
+index_i_s_sc_i                 1088
+index_i_sc_sc_i                1089
+index_i_s_s_ic                 1090
+index_i_sc_s_ic                1091
+index_i_s_sc_ic                1092
+index_i_sc_sc_ic               1093
+sprintf_s_s_p                  1094
+sprintf_s_sc_p                 1095
+sprintf_p_p_p                  1096
+new_s                          1097
+new_s_i                        1098
+new_s_ic                       1099
+stringinfo_i_s_i               1100
+stringinfo_i_sc_i              1101
+stringinfo_i_s_ic              1102
+stringinfo_i_sc_ic             1103
+upcase_s_s                     1104
+upcase_s_sc                    1105
+upcase_s                       1106
+downcase_s_s                   1107
+downcase_s_sc                  1108
+downcase_s                     1109
+titlecase_s_s                  1110
+titlecase_s_sc                 1111
+titlecase_s                    1112
+join_s_s_p                     1113
+join_s_sc_p                    1114
+split_p_s_s                    1115
+split_p_sc_s                   1116
+split_p_s_sc                   1117
+split_p_sc_sc                  1118
+charset_i_s                    1119
+charset_i_sc                   1120
+charsetname_s_i                1121
+charsetname_s_ic               1122
+find_charset_i_s               1123
+find_charset_i_sc              1124
+trans_charset_s_i              1125
+trans_charset_s_ic             1126
+trans_charset_s_s_i            1127
+trans_charset_s_sc_i           1128
+trans_charset_s_s_ic           1129
+trans_charset_s_sc_ic          1130
+encoding_i_s                   1131
+encoding_i_sc                  1132
+encodingname_s_i               1133
+encodingname_s_ic              1134
+find_encoding_i_s              1135
+find_encoding_i_sc             1136
+trans_encoding_s_i             1137
+trans_encoding_s_ic            1138
+trans_encoding_s_s_i           1139
+trans_encoding_s_sc_i          1140
+trans_encoding_s_s_ic          1141
+trans_encoding_s_sc_ic         1142
+is_cclass_i_i_s_i              1143
+is_cclass_i_ic_s_i             1144
+is_cclass_i_i_sc_i             1145
+is_cclass_i_ic_sc_i            1146
+is_cclass_i_i_s_ic             1147
+is_cclass_i_ic_s_ic            1148
+is_cclass_i_i_sc_ic            1149
+is_cclass_i_ic_sc_ic           1150
+find_cclass_i_i_s_i_i          1151
+find_cclass_i_ic_s_i_i         1152
+find_cclass_i_i_sc_i_i         1153
+find_cclass_i_ic_sc_i_i        1154
+find_cclass_i_i_s_ic_i         1155
+find_cclass_i_ic_s_ic_i        1156
+find_cclass_i_i_sc_ic_i        1157
+find_cclass_i_ic_sc_ic_i       1158
+find_cclass_i_i_s_i_ic         1159
+find_cclass_i_ic_s_i_ic        1160
+find_cclass_i_i_sc_i_ic        1161
+find_cclass_i_ic_sc_i_ic       1162
+find_cclass_i_i_s_ic_ic        1163
+find_cclass_i_ic_s_ic_ic       1164
+find_cclass_i_i_sc_ic_ic       1165
+find_cclass_i_ic_sc_ic_ic      1166
+find_not_cclass_i_i_s_i_i      1167
+find_not_cclass_i_ic_s_i_i     1168
+find_not_cclass_i_i_sc_i_i     1169
+find_not_cclass_i_ic_sc_i_i    1170
+find_not_cclass_i_i_s_ic_i     1171
+find_not_cclass_i_ic_s_ic_i    1172
+find_not_cclass_i_i_sc_ic_i    1173
+find_not_cclass_i_ic_sc_ic_i   1174
+find_not_cclass_i_i_s_i_ic     1175
+find_not_cclass_i_ic_s_i_ic    1176
+find_not_cclass_i_i_sc_i_ic    1177
+find_not_cclass_i_ic_sc_i_ic   1178
+find_not_cclass_i_i_s_ic_ic    1179
+find_not_cclass_i_ic_s_ic_ic   1180
+find_not_cclass_i_i_sc_ic_ic   1181
+find_not_cclass_i_ic_sc_ic_ic  1182
+escape_s_s                     1183
+compose_s_s                    1184
+compose_s_sc                   1185
+spawnw_i_s                     1186
+spawnw_i_sc                    1187
+spawnw_i_p                     1188
+err_i                          1189
+err_s                          1190
+err_s_i                        1191
+err_s_ic                       1192
+time_i                         1193
+time_n                         1194
+gmtime_s_i                     1195
+gmtime_s_ic                    1196
+localtime_s_i                  1197
+localtime_s_ic                 1198
+decodetime_p_i                 1199
+decodetime_p_ic                1200
+decodelocaltime_p_i            1201
+decodelocaltime_p_ic           1202
+sysinfo_s_i                    1203
+sysinfo_s_ic                   1204
+sysinfo_i_i                    1205
+sysinfo_i_ic                   1206
+sleep_i                        1207
+sleep_ic                       1208
+sleep_n                        1209
+sleep_nc                       1210
+sizeof_i_i                     1211
+sizeof_i_ic                    1212
+store_lex_s_p                  1213
+store_lex_sc_p                 1214
+store_dynamic_lex_s_p          1215
+store_dynamic_lex_sc_p         1216
+find_lex_p_s                   1217
+find_lex_p_sc                  1218
+find_dynamic_lex_p_s           1219
+find_dynamic_lex_p_sc          1220
+find_caller_lex_p_s            1221
+find_caller_lex_p_sc           1222
+get_namespace_p                1223
+get_namespace_p_p              1224
+get_namespace_p_pc             1225
+get_hll_namespace_p            1226
+get_hll_namespace_p_p          1227
+get_hll_namespace_p_pc         1228
+get_root_namespace_p           1229
+get_root_namespace_p_p         1230
+get_root_namespace_p_pc        1231
+get_global_p_s                 1232
+get_global_p_sc                1233
+get_global_p_p_s               1234
+get_global_p_pc_s              1235
+get_global_p_p_sc              1236
+get_global_p_pc_sc             1237
+get_hll_global_p_s             1238
+get_hll_global_p_sc            1239
+get_hll_global_p_p_s           1240
+get_hll_global_p_pc_s          1241
+get_hll_global_p_p_sc          1242
+get_hll_global_p_pc_sc         1243
+get_root_global_p_s            1244
+get_root_global_p_sc           1245
+get_root_global_p_p_s          1246
+get_root_global_p_pc_s         1247
+get_root_global_p_p_sc         1248
+get_root_global_p_pc_sc        1249
+set_global_s_p                 1250
+set_global_sc_p                1251
+set_global_p_s_p               1252
+set_global_pc_s_p              1253
+set_global_p_sc_p              1254
+set_global_pc_sc_p             1255
+set_hll_global_s_p             1256
+set_hll_global_sc_p            1257
+set_hll_global_p_s_p           1258
+set_hll_global_pc_s_p          1259
+set_hll_global_p_sc_p          1260
+set_hll_global_pc_sc_p         1261
+set_root_global_s_p            1262
+set_root_global_sc_p           1263
+set_root_global_p_s_p          1264
+set_root_global_pc_s_p         1265
+set_root_global_p_sc_p         1266
+set_root_global_pc_sc_p        1267
+find_name_p_s                  1268
+find_name_p_sc                 1269
+find_sub_not_null_p_s          1270
+find_sub_not_null_p_sc         1271

Modified: trunk/src/ops/set.ops
==============================================================================
--- trunk/src/ops/set.ops	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/ops/set.ops	Wed Apr 21 10:06:00 2010	(r45852)
@@ -19,15 +19,15 @@
 
 =item B<clone>(out STR, in STR)
 
-Make a clone of $2, and put it in $1. Doesn't affect what was in
-$1. Removes the constant flag on the copy, if there was one.
+Effectively the same as set $1, $2, except that if $2 is a null STRING, $1 gets
+a new empty string instead.
 
 =cut
 
 inline op clone(out STR, in STR) :base_mem {
     /* cloning a NULL STRING produces an empty STRING; TT #964 */
     $1 = $2
-       ? Parrot_str_copy(interp, $2)
+       ? $2
        : Parrot_str_new(interp, NULL, 0);
 }
 
@@ -154,7 +154,7 @@
 }
 
 inline op set(out STR, inconst STR) :base_core {
-    $1 = Parrot_str_copy(interp, $2);
+    $1 = $2;
 }
 
 inline op set(out STR, in INT) :base_core {
@@ -186,8 +186,7 @@
 }
 
 inline op set(invar PMC, inconst STR) :base_core {
-    VTABLE_set_string_native(interp, $1,
-        Parrot_str_copy(interp, $2));
+    VTABLE_set_string_native(interp, $1, $2);
 }
 inline op set(out INT, invar PMC) :base_core {
     $1 = VTABLE_get_integer(interp, $2);
@@ -247,7 +246,7 @@
 }
 
 inline op assign(out STR, in STR) :base_core {
-    $1 = Parrot_str_set(interp, $1, $2);
+    $1 = $2;
 }
 
 inline op setref(invar PMC, invar PMC) :base_core {

Modified: trunk/src/ops/string.ops
==============================================================================
--- trunk/src/ops/string.ops	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/ops/string.ops	Wed Apr 21 10:06:00 2010	(r45852)
@@ -70,8 +70,8 @@
 
 =cut
 
-inline op chopn(inout STR, in INT) :base_core {
-    Parrot_str_chopn_inplace(interp, $1, $2);
+inline op chopn(inout STR, in INT) :base_core :deprecated {
+    $1 = Parrot_str_chopn(interp, $1, $2);
 }
 
 inline op chopn(out STR, in STR, in INT) :base_core {
@@ -97,8 +97,8 @@
 
 =cut
 
-inline op concat(inout STR, in STR) :base_mem {
-    $1 = Parrot_str_append(interp, $1, $2);
+inline op concat(inout STR, in STR) :base_mem :deprecated {
+    $1 = Parrot_str_concat(interp, $1, $2);
 }
 
 inline op concat(invar PMC, invar PMC) :base_core {
@@ -110,7 +110,7 @@
 }
 
 inline op concat(out STR, in STR, in STR) :base_mem {
-    $1 = Parrot_str_concat(interp, $2, $3, 1);
+    $1 = Parrot_str_concat(interp, $2, $3);
 }
 
 inline op concat(invar PMC, invar PMC, in STR) :base_core {
@@ -198,8 +198,8 @@
 
 inline op bytelength(out INT, in STR) :base_mem {
     UINTVAL n;
-    STRING * const s = $2;
-    if (!s)
+    const STRING * const s = $2;
+    if (STRING_IS_NULL(s))
         n = 0;
     else {
         n = s->bufused;
@@ -244,6 +244,8 @@
 
 =item B<substr>(inout STR, in INT, in INT, in STR)
 
+=item B<replace>(out STR, in STR, in INT, in INT, in STR)
+
 =item B<substr>(out STR, invar PMC, in INT, in INT)
 
 Set $1 to the portion of $2 starting at (zero-based) character position
@@ -269,25 +271,30 @@
 
 inline op substr(out STR, in STR, in INT) :base_core {
     const INTVAL len = Parrot_str_byte_length(interp, $2);
-    $1 = Parrot_str_substr(interp, $2, $3, len, &$1, 0);
+    $1 = Parrot_str_substr(interp, $2, $3, len);
 }
 
 inline op substr(out STR, in STR, in INT, in INT) :base_core {
-    $1 = Parrot_str_substr(interp, $2, $3, $4, &$1, 0);
+    $1 = Parrot_str_substr(interp, $2, $3, $4);
 }
 
-inline op substr(out STR, inout STR, in INT, in INT, in STR) :base_core {
-    $1 = Parrot_str_replace(interp, $2, $3, $4, $5, &$1);
+inline op substr(out STR, inout STR, in INT, in INT, in STR) :base_core :deprecated {
+    $1 = Parrot_str_substr(interp, $2, $3, $4);
+    $2 = Parrot_str_replace(interp, $2, $3, $4, $5);
 }
 
-inline op substr(inout STR, in INT, in INT, in STR) :base_core {
-    (void)Parrot_str_replace(interp, $1, $2, $3, $4, NULL);
+inline op substr(inout STR, in INT, in INT, in STR) :base_core :deprecated {
+    $1 = Parrot_str_replace(interp, $1, $2, $3, $4);
 }
 
 inline op substr(out STR, invar PMC, in INT, in INT) :base_core {
     $1 = VTABLE_substr_str(interp, $2, $3, $4);
 }
 
+inline op replace(out STR, in STR, in INT, in INT, in STR) :base_core {
+    $1 = Parrot_str_replace(interp, $2, $3, $4, $5);
+}
+
 
 =item B<index>(out INT, in STR, in STR)
 
@@ -429,8 +436,8 @@
     $1 = Parrot_str_upcase(interp, $2);
 }
 
-inline op upcase(inout STR) :base_core {
-    Parrot_str_upcase_inplace(interp, $1);
+inline op upcase(inout STR) :base_core :deprecated {
+    $1 = Parrot_str_upcase(interp, $1);
 }
 
 
@@ -448,8 +455,8 @@
     $1 = Parrot_str_downcase(interp, $2);
 }
 
-inline op downcase(inout STR) :base_core {
-    Parrot_str_downcase_inplace(interp, $1);
+inline op downcase(inout STR) :base_core :deprecated {
+    $1 = Parrot_str_downcase(interp, $1);
 }
 
 
@@ -467,8 +474,8 @@
     $1 = Parrot_str_titlecase(interp, $2);
 }
 
-inline op titlecase(inout STR) :base_core {
-    Parrot_str_titlecase_inplace(interp, $1);
+inline op titlecase(inout STR) :base_core :deprecated {
+    $1 = Parrot_str_titlecase(interp, $1);
 }
 
 
@@ -529,8 +536,7 @@
 }
 
 op charsetname(out STR, in INT) :base_core {
-    STRING * const name = Parrot_charset_name(interp, $2);
-    $1 = name ? Parrot_str_copy(interp, name) : NULL;
+    $1 = Parrot_charset_name(interp, $2);
 }
 
 op find_charset(out INT, in STR) :base_core {
@@ -544,13 +550,12 @@
     $1 = n;
 }
 
-op trans_charset(inout STR, in INT) {
-    $1 = Parrot_str_change_charset(interp, $1, $2, NULL);
+op trans_charset(inout STR, in INT) :deprecated {
+    $1 = Parrot_str_change_charset(interp, $1, $2);
 }
 
 op trans_charset(out STR, in STR, in INT) {
-    STRING *dest = Parrot_gc_new_string_header(interp, 0);
-    $1 = Parrot_str_change_charset(interp, $2, $3, dest);
+    $1 = Parrot_str_change_charset(interp, $2, $3);
 }
 
 
@@ -585,8 +590,7 @@
 }
 
 op encodingname(out STR, in INT) :base_core {
-    STRING * const name = Parrot_encoding_name(interp, $2);
-    $1 = name ? Parrot_str_copy(interp, name) : NULL;
+    $1 = Parrot_encoding_name(interp, $2);
 }
 
 op find_encoding(out INT, in STR) :base_core {
@@ -600,13 +604,12 @@
     $1 = n;
 }
 
-op trans_encoding(inout STR, in INT) {
-    $1 = Parrot_str_change_encoding(interp, $1, $2, NULL);
+op trans_encoding(inout STR, in INT) :deprecated {
+    $1 = Parrot_str_change_encoding(interp, $1, $2);
 }
 
 op trans_encoding(out STR, in STR, in INT) {
-    STRING * const dest = Parrot_gc_new_string_header(interp, 0);
-    $1 = Parrot_str_change_encoding(interp, $2, $3, dest);
+    $1 = Parrot_str_change_encoding(interp, $2, $3);
 }
 
 
@@ -674,7 +677,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2010, Parrot Foundation.
 
 =head1 LICENSE
 

Modified: trunk/src/packdump.c
==============================================================================
--- trunk/src/packdump.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/packdump.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -299,10 +299,10 @@
                     switch (sub->namespace_name->vtable->base_type) {
                       case enum_class_String:
                         namespace_description = Parrot_str_new(interp, "'", 1);
-                        namespace_description = Parrot_str_append(interp,
+                        namespace_description = Parrot_str_concat(interp,
                                         namespace_description,
                                         VTABLE_get_string(interp, sub->namespace_name));
-                        namespace_description = Parrot_str_append(interp,
+                        namespace_description = Parrot_str_concat(interp,
                                         namespace_description,
                                         Parrot_str_new(interp, "'", 1));
                         break;

Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/packfile.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -2449,7 +2449,7 @@
     self->size        = 0;
     self->data        = NULL;
     self->id          = 0;
-    self->name        = Parrot_str_copy(interp, name);
+    self->name        = name;
 }
 
 
@@ -2783,7 +2783,7 @@
 
     /* find seg e.g. CODE_DB => CODE and attach it */
     str_len     = Parrot_str_length(interp, debug->base.name);
-    code_name   = Parrot_str_substr(interp, debug->base.name, 0, str_len - 3, NULL, 1);
+    code_name   = Parrot_str_substr(interp, debug->base.name, 0, str_len - 3);
     code        = (PackFile_ByteCode *)PackFile_find_segment(interp, self->dir, code_name, 0);
 
     if (!code || code->base.type != PF_BYTEC_SEG) {
@@ -4324,7 +4324,7 @@
 
     /* Need to associate this segment with the applicable code segment. */
     str_len     = Parrot_str_length(interp, self->base.name);
-    code_name   = Parrot_str_substr(interp, self->base.name, 0, str_len - 4, NULL, 1);
+    code_name   = Parrot_str_substr(interp, self->base.name, 0, str_len - 4);
     code        = (PackFile_ByteCode *)PackFile_find_segment(interp,
                                 self->base.dir, code_name, 0);
 
@@ -4759,10 +4759,10 @@
 
     /* Full path to language library is "abc/abc.pbc". */
     pbc = CONST_STRING(interp, "pbc");
-    wo_ext   = Parrot_str_concat(interp, lang_name, CONST_STRING(interp, "/"), 0);
-    wo_ext   = Parrot_str_append(interp, wo_ext, lang_name);
-    file_str = Parrot_str_concat(interp, wo_ext, CONST_STRING(interp, "."), 0);
-    file_str = Parrot_str_append(interp, file_str, pbc);
+    wo_ext   = Parrot_str_concat(interp, lang_name, CONST_STRING(interp, "/"));
+    wo_ext   = Parrot_str_concat(interp, wo_ext, lang_name);
+    file_str = Parrot_str_concat(interp, wo_ext, CONST_STRING(interp, "."));
+    file_str = Parrot_str_concat(interp, file_str, pbc);
 
     /* Check if the language is already loaded */
     is_loaded_hash = VTABLE_get_pmc_keyed_int(interp,
@@ -4787,13 +4787,13 @@
     parrot_split_path_ext(interp, path, &found_path, &found_ext);
     name_length = Parrot_str_length(interp, lang_name);
     found_path = Parrot_str_substr(interp, found_path, 0,
-            Parrot_str_length(interp, found_path)-name_length, NULL, 0);
+            Parrot_str_length(interp, found_path)-name_length);
 
-    Parrot_lib_add_path(interp, Parrot_str_append(interp, found_path, CONST_STRING(interp, "include/")),
+    Parrot_lib_add_path(interp, Parrot_str_concat(interp, found_path, CONST_STRING(interp, "include/")),
             PARROT_LIB_PATH_INCLUDE);
-    Parrot_lib_add_path(interp, Parrot_str_append(interp, found_path, CONST_STRING(interp, "dynext/")),
+    Parrot_lib_add_path(interp, Parrot_str_concat(interp, found_path, CONST_STRING(interp, "dynext/")),
             PARROT_LIB_PATH_DYNEXT);
-    Parrot_lib_add_path(interp, Parrot_str_append(interp, found_path, CONST_STRING(interp, "library/")),
+    Parrot_lib_add_path(interp, Parrot_str_concat(interp, found_path, CONST_STRING(interp, "library/")),
             PARROT_LIB_PATH_LIBRARY);
 
 

Modified: trunk/src/packfile/pf_items.c
==============================================================================
--- trunk/src/packfile/pf_items.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/packfile/pf_items.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1332,7 +1332,7 @@
     TRACE_PRINTF(("size=%ld.\n", size));
 
     s = string_make_from_charset(interp, (const char *)*cursor,
-                        size, charset_nr, flags);
+                        size, charset_nr, flags | PObj_external_FLAG);
 
     /* print only printable characters */
     TRACE_PRINTF_VAL(("PF_fetch_string(): string is '%s' at 0x%x\n",

Modified: trunk/src/pbc_dump.c
==============================================================================
--- trunk/src/pbc_dump.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pbc_dump.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -155,7 +155,7 @@
 nums_dump(PARROT_INTERP, const PackFile_Segment *self)
 {
     STRING                 *debug_name = Parrot_str_concat(interp, self->name,
-            Parrot_str_new_constant(interp, "_DB"), 0);
+            Parrot_str_new_constant(interp, "_DB"));
     const PackFile_Segment *debug      = PackFile_find_segment(interp,
                                             self->dir, debug_name, 1);
 

Modified: trunk/src/pmc/bigint.pmc
==============================================================================
--- trunk/src/pmc/bigint.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/bigint.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1143,7 +1143,7 @@
 
     VTABLE STRING *get_repr() {
         STRING * const s = SELF.get_string();
-        return Parrot_str_append(INTERP, s, CONST_STRING(INTERP, "L"));
+        return Parrot_str_concat(INTERP, s, CONST_STRING(INTERP, "L"));
     }
 /*
 

Modified: trunk/src/pmc/bignum.pmc
==============================================================================
--- trunk/src/pmc/bignum.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/bignum.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1509,7 +1509,7 @@
 
     VTABLE STRING *get_repr() {
         STRING *s = SELF.get_string();
-        return Parrot_str_append(INTERP, s, Parrot_str_new(interp, "N", 1));
+        return Parrot_str_concat(INTERP, s, Parrot_str_new(interp, "N", 1));
     }
 /*
 

Modified: trunk/src/pmc/callcontext.pmc
==============================================================================
--- trunk/src/pmc/callcontext.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/callcontext.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -679,16 +679,16 @@
         for (i = 0; i < num_positionals; ++i) {
             switch (c[i].type) {
               case INTCELL:
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "I"));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "I"));
                 break;
               case FLOATCELL:
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "N"));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "N"));
                 break;
               case STRINGCELL:
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "S"));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "S"));
                 break;
               case PMCCELL:
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "P"));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "P"));
                 break;
               default:
                 PARROT_FAILURE("Impossible flag");
@@ -1429,7 +1429,7 @@
             SET_ATTR_type_tuple(INTERP, dest, VTABLE_clone(INTERP, type_tuple));
 
         if (short_sig)
-            SET_ATTR_short_sig(INTERP, dest, Parrot_str_copy(INTERP, short_sig));
+            SET_ATTR_short_sig(INTERP, dest, short_sig);
 
         if (!PMC_IS_NULL(arg_flags))
             SET_ATTR_arg_flags(INTERP, dest, VTABLE_clone(INTERP, arg_flags));

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/class.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -203,7 +203,7 @@
         STRING * const attrib_name = VTABLE_get_string_keyed_str(
             interp, cur_attrib, name_str);
 
-        STRING * const full_key    = Parrot_str_append(interp, fq_class, attrib_name);
+        STRING * const full_key    = Parrot_str_concat(interp, fq_class, attrib_name);
 
         /* Insert into hash, along with index. */
         VTABLE_set_integer_keyed_str(interp, attrib_index, full_key, cur_index);
@@ -668,7 +668,7 @@
 */
 
     VTABLE STRING *get_string() {
-        return Parrot_str_copy(interp, make_class_name(interp, SELF));
+        return make_class_name(interp, SELF);
     }
 
 /*

Modified: trunk/src/pmc/codestring.pmc
==============================================================================
--- trunk/src/pmc/codestring.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/codestring.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -112,15 +112,13 @@
     INTVAL pos          = 0;
     INTVAL replen       = 0;
 
-    fmt = Parrot_str_new_COW(INTERP, fmt);
-
     while (pos >= 0) {
         pos += replen;
         pos = Parrot_str_find_index(INTERP, fmt, percent, pos);
         if (pos < 0)
             break;
 
-        key = Parrot_str_substr(INTERP, fmt, pos+1, 1, &key, 0);
+        key = Parrot_str_substr(INTERP, fmt, pos+1, 1);
 
         if (VTABLE_exists_keyed_str(INTERP, hash, key)) {
             repl = VTABLE_get_string_keyed_str(INTERP, hash, key);
@@ -134,14 +132,13 @@
             INTVAL I1;
 
             repl = VTABLE_get_string_keyed_int(INTERP, args, 0);
-            repl = Parrot_str_new_COW(INTERP, repl);
             I1   = VTABLE_elements(INTERP, args);
             I0   = 1;
 
             while (I0 < I1) {
                 STRING * const S0 = VTABLE_get_string_keyed_int(INTERP, args, I0);
-                repl = Parrot_str_append(INTERP, repl, comma_space);
-                repl = Parrot_str_append(INTERP, repl, S0);
+                repl = Parrot_str_concat(INTERP, repl, comma_space);
+                repl = Parrot_str_concat(INTERP, repl, S0);
                 I0++;
             }
         }
@@ -154,16 +151,16 @@
             continue;
         }
 
-        (void) Parrot_str_replace(INTERP, fmt, pos, 2, repl, NULL);
+        fmt    = Parrot_str_replace(INTERP, fmt, pos, 2, repl);
         replen = Parrot_str_byte_length(INTERP, repl);
     }
 
     /* Add a newline if necessary */
     if ('\n' != Parrot_str_indexed(INTERP, fmt, Parrot_str_byte_length(INTERP, fmt) - 1))
-        fmt = Parrot_str_concat(INTERP, fmt, newline, 0);
+        fmt = Parrot_str_concat(INTERP, fmt, newline);
 
     GET_ATTR_str_val(INTERP, SELF, S1);
-    S1 = Parrot_str_concat(INTERP, S1, fmt, 0);
+    S1 = Parrot_str_concat(INTERP, S1, fmt);
     VTABLE_set_string_native(INTERP, SELF, S1);
 
     RETURN(PMC *SELF);
@@ -258,8 +255,7 @@
         RETURN(STRING *counter_as_string);
     }
     else {
-        STRING *result = Parrot_str_copy(INTERP, format);
-        result         = Parrot_str_concat(INTERP, result, counter_as_string, 1);
+        STRING *result = Parrot_str_concat(INTERP, format, counter_as_string);
         RETURN(STRING *result);
     }
   }
@@ -284,8 +280,8 @@
     INTVAL is_unicode = 0;
     UNUSED(SELF);
 
-    escaped_str = Parrot_str_concat(INTERP, quote, escaped_str, 1);
-    escaped_str = Parrot_str_concat(INTERP, escaped_str, quote, 1);
+    escaped_str = Parrot_str_concat(INTERP, quote, escaped_str);
+    escaped_str = Parrot_str_concat(INTERP, escaped_str, quote);
     x_pos       = Parrot_str_find_index(INTERP, escaped_str, x, 0);
 
     if (x_pos != -1) {
@@ -300,7 +296,7 @@
 
     if (is_unicode) {
         STRING * const unicode = CONST_STRING(INTERP, "unicode:");
-        escaped_str            = Parrot_str_concat(INTERP, unicode, escaped_str, 1);
+        escaped_str            = Parrot_str_concat(INTERP, unicode, escaped_str);
     }
 
     RETURN(STRING *escaped_str);
@@ -367,8 +363,8 @@
                     STRING *S0   = VTABLE_get_string_keyed_int(INTERP, P0, index2);
                     (STRING *S0) = PCCINVOKE(INTERP, SELF, "escape", STRING *S0);
                     if (prefix)
-                        out = Parrot_str_append(INTERP, out, prefix);
-                    out    = Parrot_str_append(INTERP, out, S0);
+                        out = Parrot_str_concat(INTERP, out, prefix);
+                    out    = Parrot_str_concat(INTERP, out, S0);
                     prefix = semi;
                 }
             }
@@ -376,14 +372,14 @@
                 STRING *S0   = VTABLE_get_string_keyed_int(INTERP, args, index);
                 (STRING *S0) = PCCINVOKE(INTERP, SELF, "escape", STRING *S0);
                 if (prefix)
-                    out = Parrot_str_append(INTERP, out, prefix);
-                out    = Parrot_str_append(INTERP, out, S0);
+                    out = Parrot_str_concat(INTERP, out, prefix);
+                out    = Parrot_str_concat(INTERP, out, S0);
                 prefix = semi;
             }
         }
     }
 
-    out = Parrot_str_append(INTERP, out, close_bracket);
+    out = Parrot_str_concat(INTERP, out, close_bracket);
 
     RETURN(STRING *out);
 }

Modified: trunk/src/pmc/coroutine.pmc
==============================================================================
--- trunk/src/pmc/coroutine.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/coroutine.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -120,9 +120,6 @@
                 (Parrot_Coroutine_attributes *)PMC_data(SELF),
                 sizeof (Parrot_Coroutine_attributes));
 
-        GET_ATTR_name(INTERP, ret, name);
-        SET_ATTR_name(INTERP, ret, Parrot_str_copy(INTERP, name));
-
         return ret;
     }
 

Modified: trunk/src/pmc/eventhandler.pmc
==============================================================================
--- trunk/src/pmc/eventhandler.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/eventhandler.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -167,9 +167,9 @@
         Parrot_EventHandler_attributes * const e = PARROT_EVENTHANDLER(SELF);
 
         if (e)
-            return Parrot_str_copy(INTERP, e->type);
+            return e->type;
 
-        return string_from_literal(INTERP, "");
+        return CONST_STRING(INTERP, "");
     }
 
 /*

Modified: trunk/src/pmc/filehandle.pmc
==============================================================================
--- trunk/src/pmc/filehandle.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/filehandle.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -253,10 +253,10 @@
                                 "Cannot reopen already open filehandle");
 
         if (got_mode && !STRING_IS_NULL(mode))
-            SET_ATTR_mode(INTERP, SELF, Parrot_str_copy(INTERP, mode));
+            SET_ATTR_mode(INTERP, SELF, mode);
 
         if (got_filename && !STRING_IS_NULL(filename))
-            SET_ATTR_filename(INTERP, SELF, Parrot_str_copy(INTERP, filename));
+            SET_ATTR_filename(INTERP, SELF, filename);
 
         /* Open the file. With no options, reopen the same file as before */
         GET_ATTR_filename(INTERP, SELF, open_filename);
@@ -475,7 +475,7 @@
 
             do {
                 STRING * const part = Parrot_io_reads(INTERP, SELF, 0);
-                result = Parrot_str_append(INTERP, result, part);
+                result = Parrot_str_concat(INTERP, result, part);
 
                 if (Parrot_io_eof(INTERP, SELF))
                     break;
@@ -618,12 +618,9 @@
 */
 
     METHOD mode() {
-        STRING *mode, *mode_copy;
-
+        STRING *mode;
         GET_ATTR_mode(INTERP, SELF, mode);
-        mode_copy = Parrot_str_copy(INTERP, mode);
-
-        RETURN(STRING *mode_copy);
+        RETURN(STRING *mode);
     }
 
 
@@ -640,20 +637,14 @@
 
     METHOD encoding(STRING *new_encoding :optional, INTVAL got_encoding :opt_flag) {
         STRING *encoding;
-        STRING *encoding_copy = NULL;
 
         if (got_encoding) {
-            if (!STRING_IS_NULL(new_encoding))
-                encoding_copy = Parrot_str_copy(INTERP, new_encoding);
-            SET_ATTR_encoding(INTERP, SELF, encoding_copy);
+            SET_ATTR_encoding(INTERP, SELF, new_encoding);
             RETURN(STRING *new_encoding);
         }
 
         GET_ATTR_encoding(INTERP, SELF, encoding);
-        if (!STRING_IS_NULL(encoding))
-            encoding_copy = Parrot_str_copy(INTERP, encoding);
-
-        RETURN(STRING *encoding_copy);
+        RETURN(STRING *encoding);
     }
 
 

Modified: trunk/src/pmc/fixedbooleanarray.pmc
==============================================================================
--- trunk/src/pmc/fixedbooleanarray.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/fixedbooleanarray.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -283,9 +283,9 @@
 
         for (i = 0; i < elems; i++) {
             if (SELF.get_integer_keyed_int((INTVAL)i))
-                str = Parrot_str_concat(INTERP, str, one, 0);
+                str = Parrot_str_concat(INTERP, str, one);
             else
-                str = Parrot_str_concat(INTERP, str, zero, 0);
+                str = Parrot_str_concat(INTERP, str, zero);
         }
 
         return str;

Modified: trunk/src/pmc/fixedintegerarray.pmc
==============================================================================
--- trunk/src/pmc/fixedintegerarray.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/fixedintegerarray.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -279,13 +279,13 @@
 
         for (j = 0; j < n; ++j) {
             PMC * const val = SELF.get_pmc_keyed_int(j);
-            res = Parrot_str_append(INTERP, res, VTABLE_get_repr(INTERP, val));
+            res = Parrot_str_concat(INTERP, res, VTABLE_get_repr(INTERP, val));
 
             if (j < n - 1)
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ", "));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ", "));
         }
 
-        res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, " ]"));
+        res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, " ]"));
         return res;
     }
 

Modified: trunk/src/pmc/fixedpmcarray.pmc
==============================================================================
--- trunk/src/pmc/fixedpmcarray.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/fixedpmcarray.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -222,12 +222,12 @@
         for (i = 0; i < n; ++i) {
             PMC * const val = SELF.get_pmc_keyed_int(i);
             if (i > 0)
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ", "));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ", "));
 
-            res = Parrot_str_append(INTERP, res, VTABLE_get_repr(INTERP, val));
+            res = Parrot_str_concat(INTERP, res, VTABLE_get_repr(INTERP, val));
         }
 
-        res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ")"));
+        res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ")"));
 
         return res;
     }

Modified: trunk/src/pmc/fixedstringarray.pmc
==============================================================================
--- trunk/src/pmc/fixedstringarray.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/fixedstringarray.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -538,15 +538,15 @@
 
         for (j = 0; j < n; ++j) {
             STRING * const val = SELF.get_string_keyed_int(j);
-            res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "\""));
-            res = Parrot_str_append(INTERP, res, val);
-            res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "\""));
+            res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "\""));
+            res = Parrot_str_concat(INTERP, res, val);
+            res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "\""));
 
             if (j < n - 1)
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ", "));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ", "));
         }
 
-        res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, " ]"));
+        res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, " ]"));
         return res;
     }
 

Modified: trunk/src/pmc/hash.pmc
==============================================================================
--- trunk/src/pmc/hash.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/hash.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -342,23 +342,23 @@
             Parrot_str_free_cstring(key_str);
 
             if (all_digit) {
-                res = Parrot_str_append(INTERP, res, key);
+                res = Parrot_str_concat(INTERP, res, key);
             }
             else {
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "'"));
-                res = Parrot_str_append(INTERP, res, key);
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "'"));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "'"));
+                res = Parrot_str_concat(INTERP, res, key);
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "'"));
             }
 
-            res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ": "));
+            res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ": "));
             val = SELF.get_pmc_keyed_str(key);
-            res = Parrot_str_append(INTERP, res, VTABLE_get_string(INTERP, val));
+            res = Parrot_str_concat(INTERP, res, VTABLE_get_string(INTERP, val));
 
             if (j < n - 1)
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ", "));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ", "));
         }
 
-        res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, "}"));
+        res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "}"));
 
         return res;
     }

Modified: trunk/src/pmc/key.pmc
==============================================================================
--- trunk/src/pmc/key.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/key.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -74,8 +74,7 @@
                 break;
               case KEY_string_FLAG:
               case KEY_string_FLAG | KEY_register_FLAG:
-                key_set_string(INTERP, dkey,
-                        Parrot_str_copy(INTERP, VTABLE_get_string(INTERP, key)));
+                key_set_string(INTERP, dkey, VTABLE_get_string(INTERP, key));
                 break;
               case KEY_pmc_FLAG:
               case KEY_pmc_FLAG | KEY_register_FLAG:

Modified: trunk/src/pmc/namespace.pmc
==============================================================================
--- trunk/src/pmc/namespace.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/namespace.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -166,7 +166,7 @@
 
         if (Parrot_str_equal(interp, sub->method_name, CONST_STRING(interp, ""))) {
             if (sub->vtable_index != -1 && !STRING_IS_NULL(vtable_key)) {
-                method_name = Parrot_str_copy(interp, vtable_key);
+                method_name = vtable_key;
             }
         }
         else {

Modified: trunk/src/pmc/object.pmc
==============================================================================
--- trunk/src/pmc/object.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/object.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -119,7 +119,7 @@
 
         /* Build a string representing the fully qualified attribute name. */
         STRING *fq_name = VTABLE_get_string(interp, cur_class);
-        fq_name         = Parrot_str_append(interp, fq_name, name);
+        fq_name         = Parrot_str_concat(interp, fq_name, name);
 
         /* Look up. */
         if (VTABLE_exists_keyed_str(interp, _class->attrib_index, fq_name)) {
@@ -160,7 +160,7 @@
     /* Build a string representing the fully qualified attribute name. */
     parent_class = Parrot_oo_get_class(interp, key);
     fq_name      = VTABLE_get_string(interp, parent_class);
-    fq_name      = Parrot_str_append(interp, fq_name, name);
+    fq_name      = Parrot_str_concat(interp, fq_name, name);
 
     /* Look up. */
     if (VTABLE_exists_keyed_str(interp, _class->attrib_index, fq_name)) {

Modified: trunk/src/pmc/packfiledirectory.pmc
==============================================================================
--- trunk/src/pmc/packfiledirectory.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/packfiledirectory.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -148,7 +148,7 @@
             PackFile_Segment * const pfseg = (PackFile_Segment *)VTABLE_get_pointer(interp, seg);
 
             pfseg->pf   = pf;
-            pfseg->name = Parrot_str_copy(interp, name);
+            pfseg->name = name;
             PackFile_add_segment(interp, pfdir, pfseg);
         }
 

Modified: trunk/src/pmc/parrotinterpreter.pmc
==============================================================================
--- trunk/src/pmc/parrotinterpreter.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/parrotinterpreter.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -145,7 +145,7 @@
                 Parrot_Class_attributes * const source_class = PARROT_CLASS(source);
                 Parrot_Class_attributes * const dest_class   = PARROT_CLASS(dest);
 
-                dest_class->name           = Parrot_str_copy(d, source_class->name);
+                dest_class->name           = source_class->name;
                 dest_class->_namespace     = VTABLE_clone(d, source_class->_namespace);
             }
         }

Modified: trunk/src/pmc/pmcproxy.pmc
==============================================================================
--- trunk/src/pmc/pmcproxy.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/pmcproxy.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -486,9 +486,7 @@
 
     VTABLE STRING *get_string() {
         Parrot_Class_attributes * const proxy_info = PARROT_CLASS(SELF);
-
-        /* Copy the stored string name of the proxy. */
-        return Parrot_str_copy(interp, proxy_info->name);
+        return proxy_info->name;
     }
 
 

Modified: trunk/src/pmc/resizablepmcarray.pmc
==============================================================================
--- trunk/src/pmc/resizablepmcarray.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/resizablepmcarray.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -391,9 +391,14 @@
     }
 
     VTABLE void push_pmc(PMC *value) {
+        const INTVAL size   = PMC_size(SELF);
+        const INTVAL thresh = PMC_threshold(SELF);
 
-        const INTVAL size = PMC_size(SELF);
-        SELF.set_integer_native(size + 1);
+        if (PMC_array(SELF) && size < thresh)
+            PMC_size(SELF) = size + 1;
+        else {
+            SELF.set_integer_native(size + 1);
+        }
         ((PMC **)PMC_array(SELF))[size] = value;
 
         return;
@@ -655,13 +660,13 @@
 
         for (j = 0; j < n; ++j) {
             PMC * const val = SELF.get_pmc_keyed_int(j);
-            res      = Parrot_str_append(INTERP, res, VTABLE_get_repr(INTERP, val));
+            res      = Parrot_str_concat(INTERP, res, VTABLE_get_repr(INTERP, val));
 
             if (j < n - 1)
-                res = Parrot_str_append(INTERP, res, CONST_STRING(INTERP, ", "));
+                res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ", "));
         }
 
-        return Parrot_str_append(INTERP, res, CONST_STRING(INTERP, " ]"));
+        return Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, " ]"));
     }
 
 /*

Modified: trunk/src/pmc/role.pmc
==============================================================================
--- trunk/src/pmc/role.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/role.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -515,7 +515,7 @@
         }
 
         /* Otherwise, copy the stored string name of the class. */
-        return Parrot_str_copy(interp, role->name);
+        return role->name;
     }
 
 /*

Modified: trunk/src/pmc/scalar.pmc
==============================================================================
--- trunk/src/pmc/scalar.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/scalar.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -632,7 +632,7 @@
 
     VTABLE PMC *concatenate(PMC *value, PMC *dest) {
         STRING * const s = Parrot_str_concat(INTERP, SELF.get_string(),
-            VTABLE_get_string(INTERP, value), 0);
+            VTABLE_get_string(INTERP, value));
 
         dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
 
@@ -642,7 +642,7 @@
 
     VTABLE PMC *concatenate_str(STRING *value, PMC *dest) {
         STRING * const s = Parrot_str_concat(INTERP,
-            SELF.get_string(), value, 0);
+            SELF.get_string(), value);
 
         dest = Parrot_pmc_new(INTERP, VTABLE_type(INTERP, SELF));
 
@@ -653,12 +653,12 @@
     VTABLE void i_concatenate(PMC *value) {
         STRING * const s = SELF.get_string();
         STRING * const v = VTABLE_get_string(INTERP, value);
-        SELF.set_string_native(Parrot_str_append(INTERP, s, v));
+        SELF.set_string_native(Parrot_str_concat(INTERP, s, v));
     }
 
     VTABLE void i_concatenate_str(STRING *value) {
         STRING * const s = SELF.get_string();
-        SELF.set_string_native(Parrot_str_append(INTERP, s, value));
+        SELF.set_string_native(Parrot_str_concat(INTERP, s, value));
     }
 
 /*
@@ -924,7 +924,7 @@
 
     VTABLE STRING *substr_str(INTVAL offset, INTVAL length) {
         return Parrot_str_substr(INTERP, VTABLE_get_string(INTERP, SELF),
-            offset, length, NULL, 0);
+                offset, length);
     }
 
 /*

Modified: trunk/src/pmc/string.pmc
==============================================================================
--- trunk/src/pmc/string.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/string.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -125,8 +125,7 @@
     VTABLE STRING *get_string() {
         STRING *str_val;
         GET_ATTR_str_val(INTERP, SELF, str_val);
-
-        return STRING_IS_NULL(str_val) ? STRINGNULL : Parrot_str_copy(INTERP, str_val);
+        return str_val;
     }
 
 /*
@@ -217,12 +216,7 @@
 */
 
     VTABLE void assign_string_native(STRING *value) {
-        if (!STRING_IS_NULL(value)) {
-            SET_ATTR_str_val(INTERP, SELF,
-                Parrot_str_set(INTERP, SELF.get_string(), value));
-        }
-        else
-            SET_ATTR_str_val(INTERP, SELF, NULL);
+        SET_ATTR_str_val(INTERP, SELF, value);
     }
 
 /*
@@ -375,7 +369,7 @@
     VTABLE void substr(INTVAL offset, INTVAL length, PMC *dest) {
         STRING *str_val, *s2;
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        s2 = Parrot_str_substr(INTERP, str_val, offset, length, NULL, 0);
+        s2 = Parrot_str_substr(INTERP, str_val, offset, length);
         VTABLE_set_string_native(INTERP, dest, s2);
     }
 
@@ -392,7 +386,7 @@
     VTABLE STRING *substr_str(INTVAL offset, INTVAL length) {
         STRING *str_val;
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        return Parrot_str_substr(INTERP, str_val, offset, length, NULL, 0);
+        return Parrot_str_substr(INTERP, str_val, offset, length);
     }
 
 /*
@@ -447,7 +441,7 @@
     VTABLE STRING *get_string_keyed_int(INTVAL pos) {
         STRING      *str_val;
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        return Parrot_str_substr(INTERP, str_val, pos, 1, NULL, 0);
+        return Parrot_str_substr(INTERP, str_val, pos, 1);
     }
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
@@ -478,7 +472,8 @@
         STRING      *str_val;
         const INTVAL len = Parrot_str_byte_length(INTERP, value);
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        Parrot_str_replace(INTERP, str_val, pos, len, value, NULL);
+        str_val = Parrot_str_replace(INTERP, str_val, pos, len, value);
+        SET_ATTR_str_val(INTERP, SELF, str_val);
     }
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
@@ -489,7 +484,8 @@
         STRING      *str_val;
         STRING * const c = string_chr(INTERP, (UINTVAL) value);
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        Parrot_str_replace(INTERP, str_val, pos, 1, c, NULL);
+        str_val = Parrot_str_replace(INTERP, str_val, pos, 1, c);
+        SET_ATTR_str_val(INTERP, SELF, str_val);
     }
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
@@ -512,11 +508,11 @@
     METHOD replace(STRING *orig, STRING *_new) {
         const INTVAL   old_len = Parrot_str_byte_length(INTERP, orig);
         const INTVAL   new_len = Parrot_str_byte_length(INTERP, _new);
-        STRING * const s       = VTABLE_get_string(INTERP, SELF);
+        STRING       * s       = VTABLE_get_string(INTERP, SELF);
         INTVAL         i       = 0;
 
         while (-1 != (i = Parrot_str_find_index(INTERP, s, orig, i))) {
-            (void)Parrot_str_replace(INTERP, s, i, old_len, _new, NULL);
+            s = Parrot_str_replace(INTERP, s, i, old_len, _new);
             i += new_len;
         }
 

Modified: trunk/src/pmc/stringhandle.pmc
==============================================================================
--- trunk/src/pmc/stringhandle.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/stringhandle.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -110,11 +110,11 @@
         Parrot_StringHandle_attributes * const data_struct = PARROT_STRINGHANDLE(copy);
 
         if (old_struct->stringhandle != NULL)
-            data_struct->stringhandle = Parrot_str_copy(INTERP, old_struct->stringhandle);
+            data_struct->stringhandle = old_struct->stringhandle;
         if (old_struct->mode != NULL)
-            data_struct->mode     = Parrot_str_copy(INTERP, old_struct->mode);
+            data_struct->mode     = old_struct->mode;
         if (old_struct->encoding != NULL)
-            data_struct->encoding = Parrot_str_copy(INTERP, old_struct->encoding);
+            data_struct->encoding = old_struct->encoding;
         data_struct->flags    = old_struct->flags;
 
         return copy;
@@ -182,10 +182,10 @@
         INTVAL flags;
 
         if (got_mode && !STRING_IS_NULL(mode))
-            SET_ATTR_mode(INTERP, SELF, Parrot_str_copy(INTERP, mode));
+            SET_ATTR_mode(INTERP, SELF, mode);
 
         if (got_filename && !STRING_IS_NULL(filename))
-            SET_ATTR_filename(INTERP, SELF, Parrot_str_copy(INTERP, filename));
+            SET_ATTR_filename(INTERP, SELF, filename);
 
 
         /* If StringHandle hasn't already been initialized, create a new string. */
@@ -317,8 +317,6 @@
             else
                 string_result = Parrot_str_new_constant(INTERP, "");
         }
-        else
-            string_result = Parrot_str_copy(INTERP, string_result);
 
         RETURN(STRING *string_result);
     }
@@ -378,7 +376,7 @@
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                 "Cannot write to a filehandle not opened for write");
 
-        new_string = Parrot_str_append(interp, old_string, to_print);
+        new_string = Parrot_str_concat(interp, old_string, to_print);
 
         SET_ATTR_stringhandle(INTERP, SELF, new_string);
 
@@ -464,13 +462,9 @@
 */
 
     METHOD mode() {
-        STRING *mode, *mode_copy;
-
+        STRING *mode;
         GET_ATTR_mode(INTERP, SELF, mode);
-        mode_copy = Parrot_str_copy(INTERP, mode);
-
-        RETURN(STRING *mode_copy);
-
+        RETURN(STRING *mode);
     }
 
 /*
@@ -486,21 +480,14 @@
 
     METHOD encoding(STRING *new_encoding :optional, INTVAL got_encoding :opt_flag) {
         STRING *encoding;
-        STRING *encoding_copy = NULL;
 
         if (got_encoding) {
-            if (!STRING_IS_NULL(new_encoding))
-                encoding_copy = Parrot_str_copy(INTERP, new_encoding);
-            SET_ATTR_encoding(INTERP, SELF, encoding_copy);
+            SET_ATTR_encoding(INTERP, SELF, new_encoding);
             RETURN(STRING *new_encoding);
         }
 
         GET_ATTR_encoding(INTERP, SELF, encoding);
-        if (!STRING_IS_NULL(encoding))
-            encoding_copy = Parrot_str_copy(INTERP, encoding);
-
-        RETURN(STRING *encoding_copy);
-
+        RETURN(STRING *encoding);
     }
 
 /*

Modified: trunk/src/pmc/sub.pmc
==============================================================================
--- trunk/src/pmc/sub.pmc	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/pmc/sub.pmc	Wed Apr 21 10:06:00 2010	(r45852)
@@ -252,20 +252,14 @@
 */
 
     VTABLE STRING *get_string() {
-        Parrot_Sub_attributes *sub;
-        PMC_get_sub(INTERP, SELF, sub);
-
-        if (sub->name)
-            return Parrot_str_copy(INTERP, sub->name);
-
-        return NULL;
+        STRING *name;
+        GET_ATTR_name(INTERP, SELF, name);
+        return name;
     }
 
 
     VTABLE void set_string_native(STRING *subname) {
-        Parrot_Sub_attributes *sub;
-        PMC_get_sub(INTERP, SELF, sub);
-        sub->name = Parrot_str_copy(INTERP, subname);
+        SET_ATTR_name(INTERP, SELF, subname);
     }
 
 
@@ -528,9 +522,6 @@
         /* first set the sub struct, Parrot_str_copy may cause GC */
         *sub = *dest_sub;
 
-        if (sub->name)
-            sub->name = Parrot_str_copy(INTERP, sub->name);
-
         /* Be sure not to share arg_info. */
         dest_sub->arg_info = NULL;
 
@@ -563,10 +554,6 @@
 
             /* copy the sub struct */
             memmove(my_sub, other_sub, sizeof (Parrot_Sub_attributes));
-
-            /* copy the name so it's a different string in memory */
-            if (my_sub->name)
-                my_sub->name = Parrot_str_copy(INTERP, my_sub->name);
         }
         else
             Parrot_ex_throw_from_c_args(INTERP, NULL,

Modified: trunk/src/runcore/profiling.c
==============================================================================
--- trunk/src/runcore/profiling.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/runcore/profiling.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -387,12 +387,12 @@
                 i++;
                 i++; /* the root namespace has an empty name, so ignore it */
                 for (;i < MAX_NS_DEPTH; i++) {
-                    full_ns = Parrot_str_concat(interp, full_ns, ns_names[i], 0);
-                    full_ns = Parrot_str_concat(interp, full_ns, ns_separator, 0);
+                    full_ns = Parrot_str_concat(interp, full_ns, ns_names[i]);
+                    full_ns = Parrot_str_concat(interp, full_ns, ns_separator);
                 }
 
                 GETATTR_Sub_name(interp, preop_ctx->current_sub, sub_name);
-                full_ns = Parrot_str_concat(interp, full_ns, sub_name, 0);
+                full_ns = Parrot_str_concat(interp, full_ns, sub_name);
                 full_ns_cstr = Parrot_str_to_cstring(interp, full_ns);
 
                 pprof_data[PPROF_DATA_NAMESPACE] = (PPROF_DATA) full_ns_cstr;

Modified: trunk/src/spf_render.c
==============================================================================
--- trunk/src/spf_render.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/spf_render.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -69,16 +69,15 @@
 PARROT_CANNOT_RETURN_NULL
 static STRING * handle_flags(PARROT_INTERP,
     ARGIN(const SpfInfo *info),
-    ARGMOD(STRING *str),
+    ARGIN(STRING *str),
     INTVAL is_int_type,
     ARGIN_NULLOK(STRING* prefix))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*str);
+        __attribute__nonnull__(3);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING* str_append_w_flags(PARROT_INTERP,
+static STRING* str_concat_w_flags(PARROT_INTERP,
     ARGOUT(STRING *dest),
     ARGIN(const SpfInfo *info),
     ARGMOD(STRING *src),
@@ -97,7 +96,7 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(info) \
     , PARROT_ASSERT_ARG(str))
-#define ASSERT_ARGS_str_append_w_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_str_concat_w_flags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(dest) \
     , PARROT_ASSERT_ARG(info) \
@@ -127,7 +126,7 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-handle_flags(PARROT_INTERP, ARGIN(const SpfInfo *info), ARGMOD(STRING *str),
+handle_flags(PARROT_INTERP, ARGIN(const SpfInfo *info), ARGIN(STRING *str),
         INTVAL is_int_type, ARGIN_NULLOK(STRING* prefix))
 {
     ASSERT_ARGS(handle_flags)
@@ -137,26 +136,26 @@
         if (info->flags & FLAG_PREC && info->prec == 0 &&
                 len == 1 &&
                 string_ord(interp, str, 0) == '0') {
-            Parrot_str_chopn_inplace(interp, str, len);
+            str = Parrot_str_chopn(interp, str, len);
             len = 0;
         }
         /* +, space */
         if (!len || string_ord(interp, str, 0) != '-') {
             if (info->flags & FLAG_PLUS) {
                 STRING * const cs = CONST_STRING(interp, "+");
-                str = Parrot_str_concat(interp, cs, str, 0);
+                str = Parrot_str_concat(interp, cs, str);
                 len++;
             }
             else if (info->flags & FLAG_SPACE) {
                 STRING * const cs = CONST_STRING(interp, " ");
-                str = Parrot_str_concat(interp, cs, str, 0);
+                str = Parrot_str_concat(interp, cs, str);
                 len++;
             }
         }
 
         /* # 0x ... */
         if ((info->flags & FLAG_SHARP) && prefix) {
-            str = Parrot_str_concat(interp, prefix, str, 0);
+            str = Parrot_str_concat(interp, prefix, str);
             len += Parrot_str_byte_length(interp, prefix);
         }
         /* XXX sharp + fill ??? */
@@ -178,11 +177,11 @@
     else {
         /* string precision */
         if (info->flags & FLAG_PREC && info->prec == 0) {
-            Parrot_str_chopn_inplace(interp, str, len);
+            str = Parrot_str_chopn(interp, str, len);
             len = 0;
         }
         else if (info->flags & FLAG_PREC && info->prec < len) {
-            Parrot_str_chopn_inplace(interp, str, -(INTVAL)(info->prec));
+            str = Parrot_str_chopn(interp, str, -(INTVAL)(info->prec));
             len = info->prec;
         }
     }
@@ -195,7 +194,7 @@
         STRING * const fill = Parrot_str_repeat(interp, filler, info->width - len);
 
         if (info->flags & FLAG_MINUS) { /* left-align */
-            str = Parrot_str_concat(interp, str, fill, 0);
+            str = Parrot_str_concat(interp, str, fill);
         }
         else {                  /* right-align */
             /* signed and zero padded */
@@ -204,14 +203,13 @@
                     string_ord(interp, str, 0) == '+')) {
                 STRING *temp = NULL;
                 STRING *ignored;
-                ignored = Parrot_str_substr(interp, str, 1, len-1, &temp, 0);
-                UNUSED(ignored);
-                Parrot_str_chopn_inplace(interp, str, -1);
-                str = Parrot_str_append(interp, str, fill);
-                str = Parrot_str_append(interp, str, temp);
+                temp = Parrot_str_substr(interp, str, 1, len-1);
+                str = Parrot_str_chopn(interp, str, -1);
+                str = Parrot_str_concat(interp, str, fill);
+                str = Parrot_str_concat(interp, str, temp);
             }
             else {
-                str = Parrot_str_concat(interp, fill, str, 0);
+                str = Parrot_str_concat(interp, fill, str);
             }
         }
     }
@@ -220,7 +218,7 @@
 
 /*
 
-=item C<static STRING* str_append_w_flags(PARROT_INTERP, STRING *dest, const
+=item C<static STRING* str_concat_w_flags(PARROT_INTERP, STRING *dest, const
 SpfInfo *info, STRING *src, STRING *prefix)>
 
 Used by Parrot_sprintf_format.  Prepends supplied prefix for numeric
@@ -234,12 +232,12 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING*
-str_append_w_flags(PARROT_INTERP, ARGOUT(STRING *dest), ARGIN(const SpfInfo *info),
+str_concat_w_flags(PARROT_INTERP, ARGOUT(STRING *dest), ARGIN(const SpfInfo *info),
         ARGMOD(STRING *src), ARGIN_NULLOK(STRING *prefix))
 {
-    ASSERT_ARGS(str_append_w_flags)
+    ASSERT_ARGS(str_concat_w_flags)
     src = handle_flags(interp, info, src, 1, prefix);
-    dest = Parrot_str_append(interp, dest, src);
+    dest = Parrot_str_concat(interp, dest, src);
     return dest;
 }
 
@@ -346,11 +344,9 @@
     for (i = 0; i < pat_len; i++) {
         if (string_ord(interp, pat, i) == '%') {        /* % */
             if (len) {
-                STRING *ignored
-                    = Parrot_str_substr(interp, pat, old, len, &substr, 1);
-                UNUSED(ignored);
+                substr = Parrot_str_substr(interp, pat, old, len);
                 /* XXX This shouldn't modify targ the pointer */
-                targ = Parrot_str_append(interp, targ, substr);
+                targ = Parrot_str_concat(interp, targ, substr);
             }
             len = 0;
             old = i;
@@ -604,7 +600,7 @@
                             {
                             STRING * const ts = string_chr(interp,
                                  (UINTVAL)obj->getint(interp, info.type, obj));
-                            targ = str_append_w_flags(interp, targ, &info, ts, NULL);
+                            targ = str_concat_w_flags(interp, targ, &info, ts, NULL);
                             }
                             break;
 
@@ -618,7 +614,7 @@
 
                             /* unsigned conversion - no plus */
                             info.flags &= ~FLAG_PLUS;
-                            targ        = str_append_w_flags(interp, targ,
+                            targ        = str_concat_w_flags(interp, targ,
                                             &info, ts, prefix);
                             }
                             break;
@@ -633,7 +629,7 @@
 
                             /* unsigned conversion - no plus */
                             info.flags &= ~FLAG_PLUS;
-                            targ        = str_append_w_flags(interp, targ,
+                            targ        = str_concat_w_flags(interp, targ,
                                             &info, ts, prefix);
                             }
                             break;
@@ -643,13 +639,13 @@
                             STRING * const prefix = CONST_STRING(interp, "0X");
                             const UHUGEINTVAL theuint =
                                 obj->getuint(interp, info.type, obj);
-                            STRING * const ts =
+                            STRING * ts =
                                 Parrot_str_from_uint(interp, tc, theuint, 16, 0);
-                            Parrot_str_upcase_inplace(interp, ts);
+                            ts = Parrot_str_upcase(interp, ts);
 
                             /* unsigned conversion - no plus */
                             info.flags &= ~FLAG_PLUS;
-                            targ        = str_append_w_flags(interp, targ,
+                            targ        = str_concat_w_flags(interp, targ,
                                             &info, ts, prefix);
                             }
                             break;
@@ -664,7 +660,7 @@
 
                             /* unsigned conversion - no plus */
                             info.flags &= ~FLAG_PLUS;
-                            targ        = str_append_w_flags(interp, targ,
+                            targ        = str_concat_w_flags(interp, targ,
                                             &info, ts, prefix);
                             }
                             break;
@@ -679,7 +675,7 @@
 
                             /* unsigned conversion - no plus */
                             info.flags &= ~FLAG_PLUS;
-                            targ        = str_append_w_flags(interp, targ,
+                            targ        = str_concat_w_flags(interp, targ,
                                             &info, ts, prefix);
                             }
                             break;
@@ -718,7 +714,7 @@
 #endif
                                 Parrot_str_free_cstring(tempstr);
                             }
-                            targ = Parrot_str_append(interp, targ, cstr2pstr(tc));
+                            targ = Parrot_str_concat(interp, targ, cstr2pstr(tc));
                             }
                             break;
 
@@ -730,7 +726,7 @@
                             STRING * const ts = Parrot_str_from_uint(interp, tc,
                                        (UHUGEINTVAL) (size_t) ptr, 16, 0);
 
-                            targ = str_append_w_flags(interp, targ, &info,
+                            targ = str_concat_w_flags(interp, targ, &info,
                                     ts, prefix);
                             }
                             break;
@@ -818,7 +814,7 @@
                             }
 #endif /* WIN32 */
 
-                            targ = Parrot_str_append(interp, targ, cstr2pstr(tc));
+                            targ = Parrot_str_concat(interp, targ, cstr2pstr(tc));
                             }
                             break;
 
@@ -838,7 +834,7 @@
                                                     string, 0, NULL);
                                 obj->index++;
 
-                                targ = Parrot_str_append(interp, targ, ts);
+                                targ = Parrot_str_concat(interp, targ, ts);
                                 break;
                             }
 
@@ -851,7 +847,7 @@
                             if (!STRING_IS_NULL(string)) {
                                 STRING * const ts = handle_flags(interp,
                                         &info, string, 0, NULL);
-                                targ = Parrot_str_append(interp, targ, ts);
+                                targ = Parrot_str_concat(interp, targ, ts);
                             }
                             }
                             break;
@@ -894,9 +890,8 @@
         }
     }
     if (len) {
-        STRING *ignored = Parrot_str_substr(interp, pat, old, len, &substr, 1);
-        UNUSED(ignored);
-        targ = Parrot_str_append(interp, targ, substr);
+        substr = Parrot_str_substr(interp, pat, old, len);
+        targ = Parrot_str_concat(interp, targ, substr);
     }
 
     return targ;

Modified: trunk/src/spf_vtable.c
==============================================================================
--- trunk/src/spf_vtable.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/spf_vtable.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -453,7 +453,7 @@
     obj->index++;
     s = VTABLE_get_string(interp, tmp);
     /* XXX Parrot_str_copy like below? + adjusting bufused */
-    return Parrot_str_substr(interp, s, 0, 1, NULL, 0);
+    return Parrot_str_substr(interp, s, 0, 1);
 }
 
 /*

Modified: trunk/src/string/api.c
==============================================================================
--- trunk/src/string/api.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/api.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -43,14 +43,6 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void make_writable(PARROT_INTERP,
-    ARGMOD(STRING **s),
-    const size_t len,
-    parrot_string_representation_t representation)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*s);
-
 PARROT_INLINE
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
@@ -63,9 +55,6 @@
         __attribute__nonnull__(4)
         FUNC_MODIFIES(*e);
 
-#define ASSERT_ARGS_make_writable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(s))
 #define ASSERT_ARGS_string_rep_compatible __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(a) \
     , PARROT_ASSERT_ARG(b) \
@@ -114,162 +103,6 @@
     return STRING_IS_NULL(s);
 }
 
-
-/*
-
-=item C<void Parrot_str_write_COW(PARROT_INTERP, STRING *s)>
-
-If the specified Parrot string is copy-on-write then the memory is
-copied over and the copy-on-write flag is cleared.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_str_write_COW(PARROT_INTERP, ARGMOD(STRING *s))
-{
-    ASSERT_ARGS(Parrot_str_write_COW)
-
-    /* COW_FLAG | constant_FLAG | external_FLAG) */
-    if (PObj_is_cowed_TESTALL(s)) {
-        /* Create new pool data for this header to use,
-         * independent of the original COW data */
-        PObj_constant_CLEAR(s);
-
-        /* constant may have been marked */
-        PObj_live_CLEAR(s);
-
-        if (Buffer_buflen(s)) {
-            STRING for_alloc;
-            size_t alloc_size;
-
-            PObj_flags_CLEARALL(&for_alloc);
-            alloc_size = s->bufused;
-            Parrot_gc_allocate_string_storage(interp, &for_alloc, alloc_size);
-
-            /* now copy memory over */
-            mem_sys_memcopy(for_alloc.strstart, s->strstart, alloc_size);
-
-            /* and finally use that string memory */
-
-            Buffer_bufstart(s) = Buffer_bufstart(&for_alloc);
-            s->strstart      = for_alloc.strstart;
-            Buffer_buflen(s)   = Buffer_buflen(&for_alloc);
-            PARROT_ASSERT(Buffer_buflen(s) >= alloc_size);
-        }
-
-        /* COW_FLAG | external_FLAG */
-        PObj_is_external_CLEARALL(s);
-    }
-
-    s->hashval = 0;
-}
-
-/*
-
-=item C<STRING * Parrot_str_new_COW(PARROT_INTERP, STRING *s)>
-
-Creates a copy-on-write string, cloning a string header without
-allocating a new buffer.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-STRING *
-Parrot_str_new_COW(PARROT_INTERP, ARGMOD(STRING *s))
-{
-    ASSERT_ARGS(Parrot_str_new_COW)
-    STRING *d;
-
-    if (PObj_constant_TEST(s)) {
-        d = Parrot_gc_new_string_header(interp,
-            PObj_get_FLAGS(s) & ~PObj_constant_FLAG);
-        PObj_COW_SET(s);
-        STRUCT_COPY(d, s);
-        /* we can't move the memory, because constants aren't
-         * scanned in compact_pool, therefore the other end
-         * would point to garbage.
-         */
-        PObj_constant_CLEAR(d);
-        PObj_external_SET(d);
-    }
-    else {
-        d = Parrot_gc_new_string_header(interp, PObj_get_FLAGS(s));
-        PObj_COW_SET(s);
-        STRUCT_COPY(d, s);
-        PObj_sysmem_CLEAR(d);
-    }
-    return d;
-}
-
-/*
-
-=item C<STRING * Parrot_str_reuse_COW(PARROT_INTERP, STRING *s, STRING *d)>
-
-Creates a copy-on-write string by cloning a string header without
-allocating a new buffer. Doesn't allocate a new string header, instead
-using the one passed in and returns it.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING *
-Parrot_str_reuse_COW(SHIM_INTERP, ARGMOD(STRING *s), ARGOUT(STRING *d))
-{
-    ASSERT_ARGS(Parrot_str_reuse_COW)
-
-    if (PObj_constant_TEST(s)) {
-        PObj_COW_SET(s);
-        STRUCT_COPY(d, s);
-        PObj_constant_CLEAR(d);
-        PObj_external_SET(d);
-    }
-    else {
-        PObj_COW_SET(s);
-        STRUCT_COPY(d, s);
-        PObj_sysmem_CLEAR(d);
-    }
-    return d;
-}
-
-/*
-
-=item C<STRING * Parrot_str_set(PARROT_INTERP, STRING *dest, STRING *src)>
-
-Makes the contents of first Parrot string a copy of the contents of
-second.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING *
-Parrot_str_set(PARROT_INTERP, ARGIN_NULLOK(STRING *dest), ARGMOD(STRING *src))
-{
-    ASSERT_ARGS(Parrot_str_set)
-    if (dest == src)
-        return dest;
-    if (!STRING_IS_NULL(dest)) { /* && dest != src */
-        /* they are different, dest is not an external string */
-        dest = Parrot_str_reuse_COW(interp, src, dest);
-    }
-    else
-        dest = Parrot_str_new_COW(interp, src);
-    return dest;
-}
-
-
 /*
 
 =back
@@ -298,15 +131,16 @@
     const size_t n_parrot_cstrings =
         sizeof (parrot_cstrings) / sizeof (parrot_cstrings[0]);
 
-    if (interp->parent_interpreter) {
+    if (interp->parent_interpreter)
         interp->hash_seed = interp->parent_interpreter->hash_seed;
-    }
+
     /* interp is initialized from zeroed memory, so this is fine */
     else if (interp->hash_seed == 0) {
         /* TT #64 - use an entropy source once available */
         Parrot_srand(Parrot_intval_time());
         interp->hash_seed = Parrot_uint_rand(0);
     }
+
     /* initialize the constant string table */
     if (interp->parent_interpreter) {
         interp->const_cstring_table =
@@ -345,6 +179,7 @@
     }
 }
 
+
 /*
 
 =item C<void Parrot_str_finish(PARROT_INTERP)>
@@ -360,6 +195,7 @@
 Parrot_str_finish(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_str_finish)
+
     /* all are shared between interpreters */
     if (!interp->parent_interpreter) {
         mem_internal_free(interp->const_cstring_table);
@@ -369,28 +205,6 @@
     }
 }
 
-/*
-
-=item C<UINTVAL string_capacity(PARROT_INTERP, const STRING *s)>
-
-Returns the capacity of the specified Parrot string in bytes, that
-is how many bytes can be appended onto strstart.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_PURE_FUNCTION
-UINTVAL
-string_capacity(SHIM_INTERP, ARGIN(const STRING *s))
-{
-    ASSERT_ARGS(string_capacity)
-
-    return ((ptrcast_t)Buffer_bufstart(s) + Buffer_buflen(s) -
-            (ptrcast_t)s->strstart);
-}
 
 /*
 
@@ -426,6 +240,7 @@
     return s;
 }
 
+
 /*
 
 =item C<static const CHARSET * string_rep_compatible(PARROT_INTERP, const STRING
@@ -450,6 +265,7 @@
     ARGIN(const STRING *a), ARGIN(const STRING *b), ARGOUT(const ENCODING **e))
 {
     ASSERT_ARGS(string_rep_compatible)
+
     if (a->encoding == b->encoding && a->charset == b->charset) {
         *e = a->encoding;
         return a->charset;
@@ -457,7 +273,7 @@
 
     /* a table could possibly simplify the logic */
     if (a->encoding == Parrot_utf8_encoding_ptr
-    &&  b->charset == Parrot_ascii_charset_ptr) {
+    &&  b->charset  == Parrot_ascii_charset_ptr) {
         if (a->strlen == a->bufused) {
             *e = Parrot_fixed_8_encoding_ptr;
             return b->charset;
@@ -467,7 +283,7 @@
     }
 
     if (b->encoding == Parrot_utf8_encoding_ptr
-    &&  a->charset == Parrot_ascii_charset_ptr) {
+    &&  a->charset  == Parrot_ascii_charset_ptr) {
         if (b->strlen == b->bufused) {
             *e = Parrot_fixed_8_encoding_ptr;
             return a->charset;
@@ -501,14 +317,47 @@
 
 /*
 
-=item C<STRING * Parrot_str_concat(PARROT_INTERP, STRING *a, STRING *b, UINTVAL
-Uflags)>
+=item C<STRING* Parrot_str_clone(PARROT_INTERP, const STRING *s)>
+
+Helper function to clone string.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+STRING*
+Parrot_str_clone(PARROT_INTERP, ARGIN(const STRING *s))
+{
+    ASSERT_ARGS(Parrot_str_clone)
+
+    const size_t alloc_size = s->bufused;
+    STRING * const result = Parrot_gc_new_string_header(interp, 0);
+
+    /* Copy encoding/charset/etc */
+    STRUCT_COPY(result, s);
+
+    /* Clear COW flag. We own buffer */
+    PObj_get_FLAGS(result)  = PObj_is_string_FLAG
+                            | PObj_is_COWable_FLAG
+                            | PObj_live_FLAG;
+
+    /* Allocate new chunk of memory */
+    Parrot_gc_allocate_string_storage(interp, result, alloc_size);
+
+    /* and copy it over */
+    mem_sys_memcopy(result->strstart, s->strstart, alloc_size);
+
+    return result;
+}
 
-Concatenates two Parrot strings. If necessary, converts the second
-string's encoding and/or type to match those of the first string. If
-either string is C<NULL>, then a copy of the non-C<NULL> string is
-returned. If both strings are C<NULL>, then a new zero-length string is
-created and returned.
+
+/*
+
+=item C<STRING * Parrot_str_copy(PARROT_INTERP, STRING *s)>
+
+Creates and returns a shallow copy of the specified Parrot string.
 
 =cut
 
@@ -516,52 +365,63 @@
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
 STRING *
-Parrot_str_concat(PARROT_INTERP, ARGIN_NULLOK(STRING *a),
-            ARGIN_NULLOK(STRING *b), UINTVAL Uflags)
+Parrot_str_copy(PARROT_INTERP, ARGMOD(STRING *s))
 {
-    ASSERT_ARGS(Parrot_str_concat)
-    if (a && a->strlen) {
-        if (b && b->strlen) {
-            /* don't make a copy; get the size right from the start */
-            STRING *result = Parrot_str_new_init(interp, NULL,
-                a->strlen + b->strlen, a->encoding, a->charset, Uflags);
-            result = Parrot_str_append(interp, result, a);
-            return Parrot_str_append(interp, result, b);
-        }
+    ASSERT_ARGS(Parrot_str_copy)
+    STRING *d;
 
-        return Parrot_str_copy(interp, a);
+    /* We set COW flag to avoid cloning buffer in compact_pool */
+
+    if (PObj_constant_TEST(s)) {
+        d = Parrot_gc_new_string_header(interp,
+            PObj_get_FLAGS(s) & ~PObj_constant_FLAG);
+        PObj_COW_SET(s);
+        STRUCT_COPY(d, s);
+        /* we can't move the memory, because constants aren't
+         * scanned in compact_pool, therefore the other end
+         * would point to garbage.
+         */
+        PObj_constant_CLEAR(d);
+        PObj_external_SET(d);
+    }
+    else {
+        d = Parrot_gc_new_string_header(interp, PObj_get_FLAGS(s));
+        PObj_COW_SET(s);
+        STRUCT_COPY(d, s);
+        PObj_sysmem_CLEAR(d);
     }
 
-    return b
-        ? Parrot_str_copy(interp, b)
-        : string_make(interp, NULL, 0, NULL, Uflags);
+    return d;
 }
 
 
 /*
 
-=item C<STRING * Parrot_str_append(PARROT_INTERP, STRING *a, STRING *b)>
+=item C<STRING * Parrot_str_concat(PARROT_INTERP, STRING *a, STRING *b)>
 
-Take in two Parrot strings and append the second to the first.  NOTE THAT
-RETURN VALUE MAY NOT BE THE FIRST STRING, if the first string is COW'd or
-read-only.  So make sure to _use_ the return value.
+Concatenates two Parrot strings. If necessary, converts the second
+string's encoding and/or type to match those of the first string. If
+either string is C<NULL>, then a copy of the non-C<NULL> string is
+returned. If both strings are C<NULL>, then a new zero-length string is
+created and returned.
 
 =cut
 
 */
 
 PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
+PARROT_CANNOT_RETURN_NULL
 STRING *
-Parrot_str_append(PARROT_INTERP, ARGMOD_NULLOK(STRING *a), ARGIN_NULLOK(STRING *b))
+Parrot_str_concat(PARROT_INTERP, ARGIN_NULLOK(STRING *a),
+            ARGIN_NULLOK(STRING *b))
 {
-    ASSERT_ARGS(Parrot_str_append)
-    UINTVAL a_capacity;
-    UINTVAL total_length;
-    const CHARSET *cs;
-    const ENCODING *enc;
+    ASSERT_ARGS(Parrot_str_concat)
+    const CHARSET   *cs;
+    const ENCODING  *enc;
+    STRING          *dest;
+    UINTVAL          total_length;
 
     /* XXX should this be a CHARSET method? */
 
@@ -572,16 +432,11 @@
 
     /* Is A real? */
     if (STRING_IS_NULL(a) || Buffer_bufstart(a) == NULL)
-        return Parrot_str_copy(interp, b);
+        return b;
 
     saneify_string(a);
     saneify_string(b);
 
-    /* If the destination's constant, or external then just fall back to
-       Parrot_str_concat */
-    if (PObj_is_cowed_TESTALL(a))
-        return Parrot_str_concat(interp, a, b, 0);
-
     cs = string_rep_compatible(interp, a, b, &enc);
 
     if (cs) {
@@ -594,46 +449,45 @@
            ||  b->encoding == Parrot_utf16_encoding_ptr
            ||  a->encoding == Parrot_ucs2_encoding_ptr
            ||  b->encoding == Parrot_ucs2_encoding_ptr)
-              ? Parrot_utf16_encoding_ptr
-              : Parrot_utf8_encoding_ptr;
+            ? Parrot_utf16_encoding_ptr
+            : Parrot_utf8_encoding_ptr;
 
-        Parrot_unicode_charset_ptr->to_charset(interp, a, NULL);
-        b = Parrot_unicode_charset_ptr->to_charset(interp, b,
-                Parrot_gc_new_string_header(interp, 0));
+        a = Parrot_unicode_charset_ptr->to_charset(interp, a);
+        b = Parrot_unicode_charset_ptr->to_charset(interp, b);
 
         if (a->encoding != enc)
-            enc->to_encoding(interp, a, NULL);
+            a = enc->to_encoding(interp, a);
         if (b->encoding != enc)
-            enc->to_encoding(interp, b, NULL);
+            b = enc->to_encoding(interp, b);
     }
 
     /* calc usable and total bytes */
-    a_capacity   = string_capacity(interp, a);
     total_length = a->bufused + b->bufused;
 
-    /* make sure A's big enough for both  */
-    if (total_length > a_capacity)
-        Parrot_gc_reallocate_string_storage(interp, a, total_length << 1);
+    dest = Parrot_str_new_noinit(interp, enum_stringrep_one, total_length);
+    dest->encoding = a->encoding;
+    dest->charset  = a->charset;
 
-    /* A is now ready to receive the contents of B */
+    /* Copy A first */
+    mem_sys_memcopy(dest->strstart, a->strstart, a->bufused);
 
     /* Tack B on the end of A */
-    mem_sys_memcopy((void *)((ptrcast_t)a->strstart + a->bufused),
+    mem_sys_memcopy((void *)((ptrcast_t)dest->strstart + a->bufused),
             b->strstart, b->bufused);
 
-    a->bufused += b->bufused;
-    a->strlen  += b_len;
-    a->hashval  = 0;
+    dest->bufused = a->bufused + b->bufused;
+    dest->strlen  = a->strlen + b_len;
 
-    return a;
+    return dest;
 }
 
+
 /*
 
 =item C<STRING * Parrot_str_new(PARROT_INTERP, const char * const buffer, const
 UINTVAL len)>
 
-Make a Parrot string from a specified C string.
+Makes a Parrot string from a specified C string.
 
 =cut
 
@@ -647,11 +501,14 @@
 Parrot_str_new(PARROT_INTERP, ARGIN_NULLOK(const char * const buffer), const UINTVAL len)
 {
     ASSERT_ARGS(Parrot_str_new)
-    return Parrot_str_new_init(interp, buffer, len ? len :
-            buffer ? strlen(buffer) : 0,
-                              PARROT_DEFAULT_ENCODING, PARROT_DEFAULT_CHARSET,
-                              0); /* Force an 8-bit encoding at some
-                                     point? */
+    return Parrot_str_new_init(interp, buffer,
+           len
+             ? len
+             : buffer
+                 ? strlen(buffer)
+                 : 0,
+           /* Force an 8-bit encoding at some point? */
+           PARROT_DEFAULT_ENCODING, PARROT_DEFAULT_CHARSET, 0);
 }
 
 
@@ -660,9 +517,10 @@
 =item C<STRING * Parrot_str_new_from_buffer(PARROT_INTERP, Buffer *buffer, const
 UINTVAL len)>
 
-Make a Parrot string from a Buffer.
+Makes a Parrot string from a Buffer.
 
-The Buffer is nulled afterwards - only one PObj can point at a given string pool object.
+The Buffer is nulled afterwards, as only one PObj can point at a given string
+pool object.
 
 =cut
 
@@ -676,23 +534,23 @@
 Parrot_str_new_from_buffer(PARROT_INTERP, ARGMOD(Buffer *buffer), const UINTVAL len)
 {
     ASSERT_ARGS(Parrot_str_new_from_buffer)
-    STRING *result;
 
-    result = Parrot_gc_new_string_header(interp, 0);
+    STRING *result          = Parrot_gc_new_string_header(interp, 0);
     Buffer_bufstart(result) = Buffer_bufstart(buffer);
     Buffer_buflen(result)   = Buffer_buflen(buffer);
-    result->strstart        = (char *) Buffer_bufstart(result);
+    result->strstart        = (char *)Buffer_bufstart(result);
     result->bufused         = len;
     result->strlen          = len;
     result->encoding        = Parrot_fixed_8_encoding_ptr;
     result->charset         = Parrot_binary_charset_ptr;
 
-    Buffer_bufstart(buffer) = NULL;
     Buffer_buflen(buffer)   = 0;
+    Buffer_bufstart(buffer) = NULL;
 
     return result;
 }
 
+
 /*
 
 =item C<const char* string_primary_encoding_for_representation(PARROT_INTERP,
@@ -723,6 +581,7 @@
         "invalid string representation");
 }
 
+
 /*
 
 =item C<STRING * Parrot_str_new_constant(PARROT_INTERP, const char *buffer)>
@@ -741,10 +600,9 @@
 {
     ASSERT_ARGS(Parrot_str_new_constant)
     DECL_CONST_CAST;
-    STRING *s;
     Hash   * const cstring_cache = (Hash *)interp->const_cstring_hash;
-
-    s = (STRING *)parrot_hash_get(interp, cstring_cache, buffer);
+    STRING *s                    = (STRING *)parrot_hash_get(interp,
+                                        cstring_cache, buffer);
 
     if (s)
         return s;
@@ -899,7 +757,7 @@
         if (encoding == Parrot_fixed_8_encoding_ptr)
             s->strlen = len;
         else
-            (void)Parrot_str_length(interp, s);
+            s->strlen = CHARSET_CODEPOINTS(interp, s);
 
         return s;
     }
@@ -912,7 +770,7 @@
         if (encoding == Parrot_fixed_8_encoding_ptr)
             s->strlen = len;
         else
-            (void)Parrot_str_length(interp, s);
+            s->strlen = CHARSET_CODEPOINTS(interp, s);
     }
     else {
         s->strlen = s->bufused = 0;
@@ -924,31 +782,6 @@
 
 /*
 
-=item C<STRING * Parrot_str_resize(PARROT_INTERP, STRING *s, UINTVAL addlen)>
-
-Grows the Parrot string's buffer by the specified number of characters.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING *
-Parrot_str_resize(PARROT_INTERP, ARGMOD(STRING *s), UINTVAL addlen)
-{
-    ASSERT_ARGS(Parrot_str_resize)
-    Parrot_str_write_COW(interp, s);
-
-    /* Don't check buflen, if we are here, we already checked. */
-    Parrot_gc_reallocate_string_storage(interp,
-        s, Buffer_buflen(s) + string_max_bytes(interp, s, addlen));
-    return s;
-}
-
-
-/*
-
 =back
 
 =head2 Ordinary user-visible string operations
@@ -1020,9 +853,7 @@
         ARGIN(const STRING *s2), INTVAL start)
 {
     ASSERT_ARGS(Parrot_str_find_index)
-    STRING *src, *search;
     UINTVAL len;
-    DECL_CONST_CAST;
 
     if (start < 0)
         return -1;
@@ -1037,11 +868,13 @@
 
     if (!Parrot_str_byte_length(interp, s2))
         return -1;
+    else {
+        DECL_CONST_CAST;
+        STRING *src    = PARROT_const_cast(STRING *, s);
+        STRING *search = PARROT_const_cast(STRING *, s2);
 
-    src    = PARROT_const_cast(STRING *, s);
-    search = PARROT_const_cast(STRING *, s2);
-
-    return CHARSET_INDEX(interp, src, search, (UINTVAL)start);
+        return CHARSET_INDEX(interp, src, search, (UINTVAL)start);
+    }
 }
 
 
@@ -1121,34 +954,13 @@
 
 /*
 
-=item C<STRING * Parrot_str_copy(PARROT_INTERP, STRING *s)>
-
-Creates and returns a copy of the specified Parrot string.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-STRING *
-Parrot_str_copy(PARROT_INTERP, ARGMOD(STRING *s))
-{
-    ASSERT_ARGS(Parrot_str_copy)
-    return Parrot_str_new_COW(interp, s);
-}
-
-
-/*
-
 =back
 
 =head2 Vtable Dispatch Functions
 
 =over 4
 
-=item C<INTVAL Parrot_str_length(PARROT_INTERP, STRING *s)>
+=item C<INTVAL Parrot_str_length(PARROT_INTERP, const STRING *s)>
 
 Calculates and returns the number of characters in the specified Parrot string.
 
@@ -1159,11 +971,10 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-Parrot_str_length(PARROT_INTERP, ARGMOD(STRING *s))
+Parrot_str_length(SHIM_INTERP, ARGIN(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_length)
 
-    s->strlen = CHARSET_CODEPOINTS(interp, s);
     return s->strlen;
 }
 
@@ -1190,6 +1001,7 @@
     return ENCODING_MAX_BYTES_PER_CODEPOINT(interp, s) * nchars;
 }
 
+
 /*
 
 =item C<STRING * Parrot_str_repeat(PARROT_INTERP, const STRING *s, UINTVAL num)>
@@ -1220,21 +1032,21 @@
             destpos += length;
         }
 
+        dest->strlen  = s->strlen  * num;
         dest->bufused = s->bufused * num;
-        dest->strlen  = s->strlen * num;
     }
 
     return dest;
 }
 
+
 /*
 
 =item C<STRING * Parrot_str_substr(PARROT_INTERP, STRING *src, INTVAL offset,
-INTVAL length, STRING **d, int replace_dest)>
+INTVAL length)>
 
-Copies the substring of length C<length> from C<offset> from the specified
-Parrot string and stores it in C<**d>, allocating memory if necessary. The
-substring is also returned.
+Returns substring of length C<length> from C<offset> from the specified
+Parrot string.
 
 =cut
 
@@ -1245,66 +1057,45 @@
 PARROT_WARN_UNUSED_RESULT
 STRING *
 Parrot_str_substr(PARROT_INTERP,
-        ARGIN_NULLOK(STRING *src), INTVAL offset, INTVAL length,
-        ARGOUT_NULLOK(STRING **d), int replace_dest)
+        ARGIN_NULLOK(STRING *src), INTVAL offset, INTVAL length)
 {
     ASSERT_ARGS(Parrot_str_substr)
-    if (STRING_IS_NULL(src))
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_SUBSTR_OUT_OF_STRING,
-            "Cannot substr on a null string");
-    else {
-        STRING *dest;
-        UINTVAL true_length;
-        UINTVAL true_offset = (UINTVAL)offset;
-
-        saneify_string(src);
-
-        /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */
-        if (offset == (INTVAL)Parrot_str_byte_length(interp, src) || length < 1)
-            return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
 
-        if (offset < 0)
-            true_offset = (UINTVAL)(src->strlen + offset);
+    UINTVAL true_length;
+    UINTVAL true_offset = (UINTVAL)offset;
 
-        /* 0 based... */
-        if (src->strlen == 0 || true_offset > src->strlen - 1)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_SUBSTR_OUT_OF_STRING,
-                "Cannot take substr outside string");
+    if (STRING_IS_NULL(src))
+        Parrot_ex_throw_from_c_args(interp, NULL,
+            EXCEPTION_SUBSTR_OUT_OF_STRING, "Cannot substr on a null string");
 
-        true_length = (UINTVAL)length;
-        if (true_length > (src->strlen - true_offset))
-            true_length = (UINTVAL)(src->strlen - true_offset);
+    saneify_string(src);
 
-        /* do in-place i.e. reuse existing header if one */
-        if (replace_dest && d && !STRING_IS_NULL(*d)) {
-            PARROT_ASSERT(src->encoding == Parrot_fixed_8_encoding_ptr);
-            dest           = *d;
+    /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */
+    if (offset == (INTVAL)Parrot_str_byte_length(interp, src) || length < 1)
+        return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
 
-            dest->encoding = src->encoding;
-            dest->charset  = src->charset;
+    if (offset < 0)
+        true_offset = (UINTVAL)(src->strlen + offset);
 
-            dest->strstart = (char *)src->strstart + true_offset;
-            dest->bufused  = true_length;
+    /* 0 based... */
+    if (src->strlen == 0 || true_offset > src->strlen - 1)
+        Parrot_ex_throw_from_c_args(interp, NULL,
+            EXCEPTION_SUBSTR_OUT_OF_STRING,
+            "Cannot take substr outside string");
 
-            dest->strlen   = true_length;
-            dest->hashval  = 0;
-        }
-        else
-            dest = CHARSET_GET_CODEPOINTS(interp, src, true_offset,
-                    true_length);
+    true_length = (UINTVAL)length;
 
-        if (d)
-            *d = dest;
+    if (true_length > (src->strlen - true_offset))
+        true_length = (UINTVAL)(src->strlen - true_offset);
 
-        return dest;
-    }
+    return CHARSET_GET_CODEPOINTS(interp, src, true_offset, true_length);
 }
 
 
 /*
 
 =item C<STRING * Parrot_str_replace(PARROT_INTERP, STRING *src, INTVAL offset,
-INTVAL length, STRING *rep, STRING **d)>
+INTVAL length, STRING *rep)>
 
 Replaces a sequence of C<length> characters from C<offset> in the first
 Parrot string with the second Parrot string, returning what was
@@ -1328,39 +1119,25 @@
 
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
 STRING *
 Parrot_str_replace(PARROT_INTERP, ARGIN(STRING *src),
-    INTVAL offset, INTVAL length, ARGIN(STRING *rep), ARGOUT_NULLOK(STRING **d))
+    INTVAL offset, INTVAL length, ARGIN(STRING *rep))
 {
     ASSERT_ARGS(Parrot_str_replace)
-    UINTVAL         start_byte, end_byte;
-    INTVAL          diff;
     String_iter     iter;
-
     const CHARSET  *cs;
     const ENCODING *enc;
     STRING         *dest        = NULL;
     UINTVAL         true_offset = (UINTVAL)offset;
     UINTVAL         true_length = (UINTVAL)length;
 
-    if (STRING_IS_NULL(src))
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Cannot replace on a null string");
-
-    /* special case */
-    if (d             == NULL
-    &&  src->encoding == Parrot_fixed_8_encoding_ptr
-    &&  rep->encoding == Parrot_fixed_8_encoding_ptr
-    &&  offset        >= 0
-    &&  true_offset   <  src->strlen
-    &&  length        == 1
-    &&  rep->strlen   == 1) {
-        if (PObj_is_cowed_TESTALL(src))
-            Parrot_str_write_COW(interp, src);
-
-        ((char *)src->strstart)[offset] = ((char *)rep->strstart)[0];
+    UINTVAL         start_byte, end_byte;
+    INTVAL          buf_size;
 
-        return STRINGNULL;
+    if (STRING_IS_NULL(src)) {
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
+            "Can't replace in NULL string");
     }
 
     /* abs(-offset) may not be > strlen-1 */
@@ -1372,25 +1149,19 @@
      * Only give exception if caller trys to replace end of string + 2
      */
     if (true_offset > src->strlen)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_SUBSTR_OUT_OF_STRING,
+        Parrot_ex_throw_from_c_args(interp, NULL,
+            EXCEPTION_SUBSTR_OUT_OF_STRING,
             "Can only replace inside string or index after end of string");
 
     if (true_length > (src->strlen - true_offset))
         true_length = (UINTVAL)(src->strlen - true_offset);
 
-    /* Save the substring that is replaced for the return value */
-    if (d) {
-        dest = CHARSET_GET_CODEPOINTS(interp, src, true_offset, true_length);
-        *d = dest;
-    }
-
     /* may have different reps..... */
     cs = string_rep_compatible(interp, src, rep, &enc);
 
     if (!cs) {
-        Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
-        rep = Parrot_utf16_encoding_ptr->to_encoding(interp, rep,
-                Parrot_gc_new_string_header(interp, 0));
+        src = Parrot_utf16_encoding_ptr->to_encoding(interp, src);
+        rep = Parrot_utf16_encoding_ptr->to_encoding(interp, rep);
     }
     else {
         src->charset  = cs;
@@ -1408,54 +1179,43 @@
 
     /* not possible.... */
     if (end_byte < start_byte)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_SUBSTR_OUT_OF_STRING,
+        Parrot_ex_throw_from_c_args(interp, NULL,
+            EXCEPTION_SUBSTR_OUT_OF_STRING,
             "replace: subend somehow is less than substart");
 
     /* Now do the replacement */
-    Parrot_str_write_COW(interp, src);
+    dest = Parrot_gc_new_string_header(interp, 0);
 
-    /*
-     * If the replacement string fits inside the original substring
-     * don't create a new string, just pack it.
-     */
-    diff = (end_byte - start_byte) - rep->bufused;
+    /* Copy encoding/charset/etc */
+    STRUCT_COPY(dest, src);
 
-    if (diff >= 0
-    || ((INTVAL)src->bufused - (INTVAL)Buffer_buflen(src)) <= diff) {
+    /* Clear COW flag. We own buffer */
+    PObj_get_FLAGS(dest) = PObj_is_string_FLAG
+                         | PObj_is_COWable_FLAG
+                         | PObj_live_FLAG;
 
-        if (diff != 0) {
-            mem_sys_memmove((char *)src->strstart + start_byte + rep->bufused,
-                    (char *)src->strstart + end_byte,
-                    src->bufused - end_byte);
-            src->bufused -= diff;
-        }
+            /* size            removed bytes            added bytes */
+    buf_size = src->bufused - (end_byte - start_byte) + rep->bufused;
 
-        mem_sys_memcopy((char *)src->strstart + start_byte,
-                rep->strstart, rep->bufused);
+    /* Alloctate new string size. */
+    Parrot_gc_allocate_string_storage(interp, dest, buf_size);
+    dest->bufused = buf_size;
 
-        if (diff)
-            (void)Parrot_str_length(interp, src);
-    }
+    /* Copy begin of string */
+    mem_sys_memcopy(dest->strstart, src->strstart, start_byte);
 
-    /* Replacement is larger than avail buffer, grow the string */
-    else {
-        /* diff is negative here, make it positive */
-        diff = -(diff);
-        Parrot_str_resize(interp, src, (UINTVAL)diff);
-
-        /* Move the end of old string that isn't replaced to new offset first */
-        mem_sys_memmove((char *)src->strstart + end_byte + diff,
-                (char *)src->strstart + end_byte,
-                src->bufused - end_byte);
-
-        /* Copy the replacement in */
-        mem_sys_memcopy((char *)src->strstart + start_byte, rep->strstart,
-                rep->bufused);
-        src->bufused += diff;
-        src->strlen = CHARSET_CODEPOINTS(interp, src);
-    }
+    /* Copy the replacement in */
+    mem_sys_memcopy((char *)dest->strstart + start_byte, rep->strstart,
+            rep->bufused);
+
+    /* Copy the end of old string */
+    mem_sys_memcopy((char *)dest->strstart + start_byte + rep->bufused,
+            (char *)src->strstart + end_byte,
+            src->bufused - end_byte);
+
+    dest->strlen  = CHARSET_CODEPOINTS(interp, dest);
+    dest->hashval = 0;
 
-    /* src is modified, now return the original substring */
     return dest;
 }
 
@@ -1464,9 +1224,8 @@
 
 =item C<STRING * Parrot_str_chopn(PARROT_INTERP, STRING *s, INTVAL n)>
 
-Removes the last C<n> characters of the specified Parrot string. If C<n> is
-negative, cuts the string after C<+n> characters. The returned string is a copy
-of the one passed in.
+Removes the last C<n> characters of the specified Parrot string and returns the
+modified string. If C<n> is negative, cuts the string after C<+n> characters.
 
 =cut
 
@@ -1478,68 +1237,47 @@
 Parrot_str_chopn(PARROT_INTERP, ARGMOD(STRING *s), INTVAL n)
 {
     ASSERT_ARGS(Parrot_str_chopn)
-    STRING * const chopped = Parrot_str_copy(interp, s);
-    Parrot_str_chopn_inplace(interp, chopped, n);
-    return chopped;
-}
 
-
-/*
-
-=item C<void Parrot_str_chopn_inplace(PARROT_INTERP, STRING *s, INTVAL n)>
-
-Removes the last C<n> characters of the specified Parrot string. If C<n> is
-negative, cuts the string after C<+n> characters. The string passed in is
-modified and returned.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_str_chopn_inplace(PARROT_INTERP, ARGMOD(STRING *s), INTVAL n)
-{
-    ASSERT_ARGS(Parrot_str_chopn_inplace)
+    STRING * const chopped = Parrot_str_copy(interp, s);
     UINTVAL new_length, uchar_size;
 
     if (n < 0) {
         new_length = -n;
-        if (new_length > s->strlen)
-            return;
+        if (new_length > chopped->strlen)
+            return chopped;
     }
     else {
-        if (s->strlen > (UINTVAL)n)
-            new_length = s->strlen - n;
+        if (chopped->strlen > (UINTVAL)n)
+            new_length = chopped->strlen - n;
         else
             new_length = 0;
     }
 
-    s->hashval = 0;
+    chopped->hashval = 0;
 
-    if (!new_length || !s->strlen) {
-        s->bufused = s->strlen = 0;
-        return;
+    if (!new_length || !chopped->strlen) {
+        chopped->bufused = chopped->strlen = 0;
+        return chopped;
     }
 
-    uchar_size = s->bufused / s->strlen;
-    s->strlen  = new_length;
+    uchar_size      = chopped->bufused / chopped->strlen;
+    chopped->strlen = new_length;
 
-    if (s->encoding == Parrot_fixed_8_encoding_ptr) {
-        s->bufused = new_length;
+    if (chopped->encoding == Parrot_fixed_8_encoding_ptr) {
+        chopped->bufused = new_length;
     }
-    else if (s->encoding == Parrot_ucs2_encoding_ptr) {
-        s->bufused = new_length * uchar_size;
+    else if (chopped->encoding == Parrot_ucs2_encoding_ptr) {
+        chopped->bufused = new_length * uchar_size;
     }
     else {
         String_iter iter;
 
         ENCODING_ITER_INIT(interp, s, &iter);
         iter.set_position(interp, &iter, new_length);
-        s->bufused = iter.bytepos;
+        chopped->bufused = iter.bytepos;
     }
 
-    return;
+    return chopped;
 }
 
 
@@ -1597,6 +1335,7 @@
     return !Parrot_str_equal(interp, s1, s2);
 }
 
+
 /*
 
 =item C<INTVAL Parrot_str_equal(PARROT_INTERP, const STRING *s1, const STRING
@@ -1617,6 +1356,7 @@
 Parrot_str_equal(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1), ARGIN_NULLOK(const STRING *s2))
 {
     ASSERT_ARGS(Parrot_str_equal)
+
     if ((s1 == s2) || (STRING_IS_NULL(s1) && STRING_IS_NULL(s2))) {
         return 1;
     }
@@ -1626,19 +1366,20 @@
     else if (STRING_IS_NULL(s1)) {
         return s2->strlen == 0;
     }
-    else if (s1->strlen != s2->strlen) {
-        return 0;       /* we don't care which is bigger */
-    }
-    else if (s1->hashval != s2->hashval && s1->hashval && s2->hashval) {
+
+   /* we don't care which is bigger */
+    else if (s1->strlen != s2->strlen)
         return 0;
-    }
-    else if (!s1->strlen) {   /* s2->strlen is the same here */
+    else if (s1->hashval != s2->hashval && s1->hashval && s2->hashval)
+        return 0;
+
+    /* s2->strlen is the same here */
+    else if (!s1->strlen)
         return 1;
-    }
+
     /* COWed strings */
-    else if (s1->strstart == s2->strstart && s1->bufused == s2->bufused) {
+    else if (s1->strstart == s2->strstart && s1->bufused == s2->bufused)
         return 1;
-    }
 
     /*
      * now,
@@ -1651,39 +1392,11 @@
 
 /*
 
-=item C<static void make_writable(PARROT_INTERP, STRING **s, const size_t len,
-parrot_string_representation_t representation)>
-
-Makes the specified Parrot string writable with minimum length C<len>.  The
-C<representation> argument is required in case a new Parrot string has to be
-created.
-
-=cut
-
-*/
-
-static void
-make_writable(PARROT_INTERP, ARGMOD(STRING **s),
-    const size_t len, parrot_string_representation_t representation)
-{
-    ASSERT_ARGS(make_writable)
-    if (STRING_IS_NULL(*s))
-        *s = Parrot_str_new_noinit(interp, representation, len);
-    else if ((*s)->strlen < len)
-        Parrot_str_resize(interp, *s, (UINTVAL)(len - (*s)->strlen));
-    else if (PObj_is_cowed_TESTALL(*s))
-        Parrot_str_write_COW(interp, *s);
-}
-
-
-/*
-
 =item C<STRING * Parrot_str_bitwise_and(PARROT_INTERP, const STRING *s1, const
-STRING *s2, STRING **dest)>
+STRING *s2)>
 
 Performs a bitwise C<AND> on two Parrot strings, performing type and encoding
-conversions if necessary. If the third string is not C<NULL> then it is
-reused.  Otherwise a new Parrot string is created.
+conversions if necessary. Returns the result as a new string.
 
 =cut
 
@@ -1693,7 +1406,7 @@
 PARROT_CANNOT_RETURN_NULL
 STRING *
 Parrot_str_bitwise_and(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1),
-        ARGIN_NULLOK(const STRING *s2), ARGOUT_NULLOK(STRING **dest))
+        ARGIN_NULLOK(const STRING *s2))
 {
     ASSERT_ARGS(Parrot_str_bitwise_and)
     STRING *res;
@@ -1716,14 +1429,8 @@
     else
         minlen = 0;
 
-    if (dest && !STRING_IS_NULL(*dest)) {
-        res           = *dest;
-        res->encoding = Parrot_fixed_8_encoding_ptr;
-        res->charset  = Parrot_binary_charset_ptr;
-    }
-    else
-        res = Parrot_str_new_init(interp, NULL, minlen,
-                Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
+    res = Parrot_str_new_init(interp, NULL, minlen,
+            Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
 
     if (STRING_IS_NULL(s1) || STRING_IS_NULL(s2)) {
         res->bufused = 0;
@@ -1738,8 +1445,6 @@
         Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
-    make_writable(interp, &res, minlen, enum_stringrep_one);
-
     { /* bitwise AND the strings */
         const Parrot_UInt1 *curr1 = (Parrot_UInt1 *)s1->strstart;
         const Parrot_UInt1 *curr2 = (Parrot_UInt1 *)s2->strstart;
@@ -1752,12 +1457,10 @@
 
     res->bufused = res->strlen = minlen;
 
-    if (dest)
-        *dest = res;
-
     return res;
 }
 
+
 #define BITWISE_XOR_STRINGS(type1, type2, restype, s1, s2, res, maxlen) \
 do { \
     const type1 *curr1   = NULL; \
@@ -1831,11 +1534,10 @@
 /*
 
 =item C<STRING * Parrot_str_bitwise_or(PARROT_INTERP, const STRING *s1, const
-STRING *s2, STRING **dest)>
+STRING *s2)>
 
 Performs a bitwise C<OR> on two Parrot strings, performing type and encoding
-conversions if necessary. If the third string is not C<NULL>, then it is
-reused.  Otherwise a new Parrot string is created.
+conversions if necessary.  Returns the result as a new string.
 
 =cut
 
@@ -1845,7 +1547,7 @@
 PARROT_CANNOT_RETURN_NULL
 STRING *
 Parrot_str_bitwise_or(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1),
-        ARGIN_NULLOK(const STRING *s2), ARGOUT_NULLOK(STRING **dest))
+        ARGIN_NULLOK(const STRING *s2))
 {
     ASSERT_ARGS(Parrot_str_bitwise_or)
     STRING *res;
@@ -1853,7 +1555,8 @@
 
     if (!STRING_IS_NULL(s1)) {
         if (s1->encoding != Parrot_fixed_8_encoding_ptr)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                EXCEPTION_INVALID_ENCODING,
                 "string bitwise_or (%s/%s) unsupported",
                 s1->encoding->name, nonnull_encoding_name(s2));
 
@@ -1862,7 +1565,8 @@
 
     if (!STRING_IS_NULL(s2)) {
         if (s2->encoding != Parrot_fixed_8_encoding_ptr)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                EXCEPTION_INVALID_ENCODING,
                 "string bitwise_or (%s/%s) unsupported",
                 nonnull_encoding_name(s1), s2->encoding->name);
 
@@ -1870,14 +1574,8 @@
             maxlen = s2->bufused;
     }
 
-    if (dest && !STRING_IS_NULL(*dest)) {
-        res           = *dest;
-        res->encoding = Parrot_fixed_8_encoding_ptr;
-        res->charset  = Parrot_binary_charset_ptr;
-    }
-    else
-        res = Parrot_str_new_init(interp, NULL, maxlen,
-                Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
+    res = Parrot_str_new_init(interp, NULL, maxlen,
+            Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
 
     if (!maxlen) {
         res->bufused = 0;
@@ -1891,15 +1589,10 @@
         Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
-    make_writable(interp, &res, maxlen, enum_stringrep_one);
-
     BITWISE_OR_STRINGS(Parrot_UInt1, Parrot_UInt1, Parrot_UInt1,
             s1, s2, res, maxlen);
     res->bufused = res->strlen = maxlen;
 
-    if (dest)
-        *dest = res;
-
     return res;
 }
 
@@ -1907,11 +1600,10 @@
 /*
 
 =item C<STRING * Parrot_str_bitwise_xor(PARROT_INTERP, const STRING *s1, const
-STRING *s2, STRING **dest)>
+STRING *s2)>
 
 Performs a bitwise C<XOR> on two Parrot strings, performing type and encoding
-conversions if necessary. If the third string is not C<NULL>, then it is
-reused.  Otherwise a new Parrot string is created.
+conversions if necessary.  Returns the result as a new string.
 
 =cut
 
@@ -1921,7 +1613,7 @@
 PARROT_CANNOT_RETURN_NULL
 STRING *
 Parrot_str_bitwise_xor(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1),
-        ARGIN_NULLOK(const STRING *s2), ARGOUT_NULLOK(STRING **dest))
+        ARGIN_NULLOK(const STRING *s2))
 {
     ASSERT_ARGS(Parrot_str_bitwise_xor)
     STRING *res;
@@ -1929,7 +1621,8 @@
 
     if (!STRING_IS_NULL(s1)) {
         if (s1->encoding != Parrot_fixed_8_encoding_ptr)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                EXCEPTION_INVALID_ENCODING,
                 "string bitwise_xor (%s/%s) unsupported",
                 s1->encoding->name, nonnull_encoding_name(s2));
 
@@ -1938,7 +1631,8 @@
 
     if (!STRING_IS_NULL(s2)) {
         if (s2->encoding != Parrot_fixed_8_encoding_ptr)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                EXCEPTION_INVALID_ENCODING,
                 "string bitwise_xor (%s/%s) unsupported",
                 nonnull_encoding_name(s1), s2->encoding->name);
 
@@ -1946,14 +1640,8 @@
             maxlen = s2->bufused;
     }
 
-    if (dest && !STRING_IS_NULL(*dest)) {
-        res           = *dest;
-        res->encoding = Parrot_fixed_8_encoding_ptr;
-        res->charset  = Parrot_binary_charset_ptr;
-    }
-    else
-        res = Parrot_str_new_init(interp, NULL, maxlen,
-                Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
+    res = Parrot_str_new_init(interp, NULL, maxlen,
+            Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
 
     if (!maxlen) {
         res->bufused = 0;
@@ -1967,15 +1655,10 @@
         Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
-    make_writable(interp, &res, maxlen, enum_stringrep_one);
-
     BITWISE_XOR_STRINGS(Parrot_UInt1, Parrot_UInt1, Parrot_UInt1,
             s1, s2, res, maxlen);
     res->bufused = res->strlen = maxlen;
 
-    if (dest)
-        *dest = res;
-
     return res;
 }
 
@@ -1992,13 +1675,13 @@
     } \
 } while (0)
 
+
 /*
 
-=item C<STRING * Parrot_str_bitwise_not(PARROT_INTERP, const STRING *s, STRING
-**dest)>
+=item C<STRING * Parrot_str_bitwise_not(PARROT_INTERP, const STRING *s)>
 
-Performs a bitwise C<NOT> on a Parrot string. If the second string is
-not C<NULL> then it is reused, otherwise a new Parrot string is created.
+Performs a bitwise C<NOT> on a Parrot string.  Returns the result as a new
+string.
 
 =cut
 
@@ -2007,8 +1690,7 @@
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 STRING *
-Parrot_str_bitwise_not(PARROT_INTERP, ARGIN_NULLOK(const STRING *s),
-    ARGOUT_NULLOK(STRING **dest))
+Parrot_str_bitwise_not(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_bitwise_not)
     STRING *res;
@@ -2016,7 +1698,8 @@
 
     if (!STRING_IS_NULL(s)) {
         if (s->encoding != Parrot_fixed_8_encoding_ptr)
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                EXCEPTION_INVALID_ENCODING,
                 "string bitwise_not (%s/%s) unsupported",
                 s->encoding->name, s->encoding->name);
 
@@ -2025,14 +1708,8 @@
     else
         len = 0;
 
-    if (dest && !STRING_IS_NULL(*dest)) {
-        res           = *dest;
-        res->encoding = Parrot_fixed_8_encoding_ptr;
-        res->charset  = Parrot_binary_charset_ptr;
-    }
-    else
-        res = Parrot_str_new_init(interp, NULL, len,
-                Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
+    res = Parrot_str_new_init(interp, NULL, len,
+            Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
 
     if (!len) {
         res->bufused = 0;
@@ -2046,13 +1723,9 @@
         Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
-    make_writable(interp, &res, len, enum_stringrep_one);
-
     res->strlen = res->bufused = len;
 
     BITWISE_NOT_STRING(Parrot_UInt1, s, res);
-    if (dest)
-        *dest = res;
 
     return res;
 }
@@ -2121,7 +1794,9 @@
     return output;
 }
 
+
 /*
+
 State of FSM during number value parsing.
 
 Integer uses only parse_start, parse_before_dot and parse_end.
@@ -2192,8 +1867,9 @@
                     if (i < max_safe || (i == max_safe && nextval <= last_dig))
                         i = i * 10 + nextval;
                     else
-                        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ERR_OVERFLOW,
-                                "Integer value of String '%S' too big", s);
+                        Parrot_ex_throw_from_c_args(interp, NULL,
+                            EXCEPTION_ERR_OVERFLOW,
+                            "Integer value of String '%S' too big", s);
                     state = parse_before_dot;
                 }
                 else if (c == '-') {
@@ -2215,8 +1891,9 @@
                     if (i < max_safe || (i == max_safe && nextval <= last_dig))
                         i = i * 10 + nextval;
                     else
-                        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ERR_OVERFLOW,
-                                "Integer value of String '%S' too big", s);
+                        Parrot_ex_throw_from_c_args(interp, NULL,
+                            EXCEPTION_ERR_OVERFLOW,
+                            "Integer value of String '%S' too big", s);
                 }
                 else
                     state = parse_end;
@@ -2234,6 +1911,7 @@
     }
 }
 
+
 /*
 
 =item C<FLOATVAL Parrot_str_to_num(PARROT_INTERP, const STRING *s)>
@@ -2379,16 +2057,16 @@
     }
 
     /* Support for non-canonical NaN and Inf */
-    /* charpos <=2 because for "-i" iter will be advanced to next char already */
+    /* charpos <= 2 because for "-i" iter already advanced to next char */
     if (check_nan && (iter.charpos <= 2)) {
         STRING *t = Parrot_str_upcase(interp, s);
         if (Parrot_str_equal(interp, t, CONST_STRING(interp, "NAN")))
             return PARROT_FLOATVAL_NAN_QUIET;
         else if (Parrot_str_equal(interp, t, CONST_STRING(interp, "INF"))
-                || Parrot_str_equal(interp, t, CONST_STRING(interp, "INFINITY")))
+             ||  Parrot_str_equal(interp, t, CONST_STRING(interp, "INFINITY")))
             return PARROT_FLOATVAL_INF_POSITIVE;
         else if (Parrot_str_equal(interp, t, CONST_STRING(interp, "-INF"))
-                || Parrot_str_equal(interp, t, CONST_STRING(interp, "-INFINITY")))
+             ||  Parrot_str_equal(interp, t, CONST_STRING(interp, "-INFINITY")))
             return PARROT_FLOATVAL_INF_NEGATIVE;
         else
             return 0.0;
@@ -2472,8 +2150,8 @@
 =item C<char * Parrot_str_to_cstring(PARROT_INTERP, const STRING *s)>
 
 Returns a C string for the specified Parrot string. Use
-C<Parrot_str_free_cstring()> to free the string. Failure to do this will result in
-a memory leak.
+C<Parrot_str_free_cstring()> to free the string. Failure to do this will result
+in a memory leak.
 
 =cut
 
@@ -2486,12 +2164,13 @@
 Parrot_str_to_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_to_cstring)
+
     if (STRING_IS_NULL(s)) {
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
             "Can't convert NULL string");
     }
-    else
-      return string_to_cstring_nullable(interp, s);
+
+    return string_to_cstring_nullable(interp, s);
 }
 
 
@@ -2500,8 +2179,9 @@
 =item C<char * string_to_cstring_nullable(PARROT_INTERP, const STRING *s)>
 
 Returns a C string for the specified Parrot string. Use
-C<Parrot_str_free_cstring()> to free the string. Failure to do this will result in
-a memory leak.
+C<Parrot_str_free_cstring()> to free the string, if it's not NULL. Failure to
+do this will result in a memory leak.  Failure to check if the return value is
+NULL will result in embarrassment for you.
 
 =cut
 
@@ -2559,24 +2239,15 @@
 
 PARROT_EXPORT
 void
-Parrot_str_pin(PARROT_INTERP, ARGMOD(STRING *s))
+Parrot_str_pin(SHIM_INTERP, ARGMOD(STRING *s))
 {
     ASSERT_ARGS(Parrot_str_pin)
-    char  *memory;
-    size_t size;
-
-    /* XXX -lt: COW strings have the external_FLAG set, so this will
-     *          not work for these
-     *          so probably only sysmem should be tested
-     */
-    Parrot_str_write_COW(interp, s);
-
-    size   = Buffer_buflen(s);
-    memory = (char *)mem_internal_allocate(size);
+    size_t size   = Buffer_buflen(s);
+    char  *memory = (char *)mem_internal_allocate(size);
 
     mem_sys_memcopy(memory, Buffer_bufstart(s), size);
     Buffer_bufstart(s) = memory;
-    s->strstart      = memory;
+    s->strstart        = memory;
 
     /* Mark the memory as both from the system and immobile */
     PObj_sysmem_SET(s);
@@ -2602,12 +2273,10 @@
     size_t size;
 
     /* If this string is not marked using system memory,
-     * we just don't do this
-     */
+     * we just don't do this */
     if (!PObj_sysmem_TEST(s))
         return;
 
-    Parrot_str_write_COW(interp, s);
     size = Buffer_buflen(s);
 
     /* We need a handle on the fixed memory so we can get rid of it later */
@@ -2812,7 +2481,7 @@
         else
             hex = Parrot_sprintf_c(interp, "\\u%04x", c);
 
-        result = Parrot_str_append(interp, result, hex);
+        result = Parrot_str_concat(interp, result, hex);
 
         /* adjust our insert idx */
         i += hex->strlen;
@@ -2934,7 +2603,7 @@
 
     /* Force validating the string */
     if (encoding != result->encoding)
-        (void)Parrot_str_length(interp, result);
+        result->strlen = CHARSET_CODEPOINTS(interp, result);
 
     if (!CHARSET_VALIDATE(interp, result))
         Parrot_ex_throw_from_c_args(interp, NULL,
@@ -2962,41 +2631,13 @@
 Parrot_str_upcase(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_upcase)
-    if (STRING_IS_NULL(s)) {
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
-            "Can't upcase NULL string");
-    }
-    else {
-        DECL_CONST_CAST;
-        STRING * const dest = Parrot_str_copy(interp, PARROT_const_cast(STRING *, s));
-        Parrot_str_upcase_inplace(interp, dest);
-        return dest;
-    }
-}
-
-
-/*
-
-=item C<void Parrot_str_upcase_inplace(PARROT_INTERP, STRING *s)>
-
-Converts the specified Parrot string to upper case.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_str_upcase_inplace(PARROT_INTERP, ARGMOD_NULLOK(STRING *s))
-{
-    ASSERT_ARGS(Parrot_str_upcase_inplace)
-    if (STRING_IS_NULL(s)) {
+    if (STRING_IS_NULL(s))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
             "Can't upcase NULL string");
-    }
     else {
-        Parrot_str_write_COW(interp, s);
-        CHARSET_UPCASE(interp, s);
+        STRING * res = CHARSET_UPCASE(interp, s);
+        res->hashval = 0;
+        return res;
     }
 }
 
@@ -3019,47 +2660,14 @@
 Parrot_str_downcase(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_downcase)
-    if (STRING_IS_NULL(s)) {
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
-            "Can't downcase NULL string");
-    }
-    else {
-        DECL_CONST_CAST;
-        STRING * const dest = Parrot_str_copy(interp, PARROT_const_cast(STRING *, s));
-        Parrot_str_downcase_inplace(interp, dest);
-        return dest;
-    }
-}
-
-
-/*
-
-=item C<void Parrot_str_downcase_inplace(PARROT_INTERP, STRING *s)>
-
-Converts the specified Parrot string to lower case.
-
-=cut
-
-*/
 
-PARROT_EXPORT
-void
-Parrot_str_downcase_inplace(PARROT_INTERP, ARGMOD_NULLOK(STRING *s))
-{
-    ASSERT_ARGS(Parrot_str_downcase_inplace)
-    if (STRING_IS_NULL(s)) {
+    if (STRING_IS_NULL(s))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
             "Can't downcase NULL string");
-    }
     else {
-        /*
-         * TODO get rid of all the inplace variants. We have for utf8:
-         * * 1 Parrot_str_copy from the non-incase variant
-         * * conversion to utf16, with doubling the buffer
-         * * possibly one more reallocation in downcase
-         */
-        Parrot_str_write_COW(interp, s);
-        CHARSET_DOWNCASE(interp, s);
+        STRING * res = CHARSET_DOWNCASE(interp, s);
+        res->hashval = 0;
+        return res;
     }
 }
 
@@ -3082,41 +2690,14 @@
 Parrot_str_titlecase(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_titlecase)
-    if (STRING_IS_NULL(s)) {
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
-            "Can't titlecase NULL string");
-    }
-    else {
-        DECL_CONST_CAST;
-        STRING * const dest = Parrot_str_copy(interp, PARROT_const_cast(STRING *, s));
-        Parrot_str_titlecase_inplace(interp, dest);
-        return dest;
-    }
-}
-
-
-/*
-
-=item C<void Parrot_str_titlecase_inplace(PARROT_INTERP, STRING *s)>
-
-Converts the specified Parrot string to title case.
-
-=cut
 
-*/
-
-PARROT_EXPORT
-void
-Parrot_str_titlecase_inplace(PARROT_INTERP, ARGMOD_NULLOK(STRING *s))
-{
-    ASSERT_ARGS(Parrot_str_titlecase_inplace)
-    if (STRING_IS_NULL(s)) {
+    if (STRING_IS_NULL(s))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
             "Can't titlecase NULL string");
-    }
     else {
-        Parrot_str_write_COW(interp, s);
-        CHARSET_TITLECASE(interp, s);
+        STRING * res = CHARSET_TITLECASE(interp, s);
+        res->hashval = 0;
+        return res;
     }
 }
 
@@ -3176,7 +2757,7 @@
 Parrot_string_cstring(SHIM_INTERP, ARGIN(const STRING *str))
 {
     ASSERT_ARGS(Parrot_string_cstring)
-    /* TODO handle NUL and friends */
+    /* TODO handle NULL and friends */
     return str->strstart;
 }
 
@@ -3201,6 +2782,7 @@
         ARGIN(const STRING *s), UINTVAL offset)
 {
     ASSERT_ARGS(Parrot_str_is_cclass)
+
     if (!Parrot_str_byte_length(interp, s))
         return 0;
 
@@ -3227,12 +2809,14 @@
                           UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(Parrot_str_find_cclass)
+
     if (STRING_IS_NULL(s))
         return -1;
 
     return CHARSET_FIND_CCLASS(interp, flags, s, offset, count);
 }
 
+
 /*
 
 =item C<INTVAL Parrot_str_find_not_cclass(PARROT_INTERP, INTVAL flags, STRING
@@ -3254,6 +2838,7 @@
     ARGIN_NULLOK(STRING *s), UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(Parrot_str_find_not_cclass)
+
     if (STRING_IS_NULL(s))
         return -1;
 
@@ -3264,10 +2849,10 @@
 /*
 
 =item C<STRING* Parrot_str_change_charset(PARROT_INTERP, STRING *src, INTVAL
-charset_nr, STRING *dest)>
+charset_nr)>
 
-If C<dest> == NULL, converts C<src> to the given charset or encoding inplace.
-Otherwise returns a copy of C<src> with the charset/encoding in C<dest>.
+Converts C<src> to the given charset or encoding and returns the result as a
+new string.
 
 =cut
 
@@ -3278,7 +2863,7 @@
 PARROT_CAN_RETURN_NULL
 STRING*
 Parrot_str_change_charset(PARROT_INTERP, ARGMOD_NULLOK(STRING *src),
-        INTVAL charset_nr, ARGOUT_NULLOK(STRING *dest))
+        INTVAL charset_nr)
 {
     ASSERT_ARGS(Parrot_str_change_charset)
     const CHARSET *new_charset;
@@ -3292,41 +2877,20 @@
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_CHARTYPE,
                 "charset #%d not found", (int) charset_nr);
 
-    /*
-     * dest is an empty string header or NULL, if an inplace
-     * operation is desired
-     */
-    if (!STRING_IS_NULL(dest)) {
-        if (new_charset == src->charset) {
-            dest          = Parrot_str_reuse_COW(interp, src, dest);
-            dest->charset = new_charset;
-            /* keep encoding */
-            return dest;
-        }
-
-        dest->charset  = new_charset;
-
-        /* get prefered encoding for charset */
-        dest->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, dest);
-    }
-    else {
-        if (new_charset == src->charset)
-            return src;
-
-        Parrot_str_write_COW(interp, src);
-    }
+    if (new_charset == src->charset)
+        return src;
 
-    return new_charset->to_charset(interp, src, dest);
+    return new_charset->to_charset(interp, src);
 }
 
 
 /*
 
 =item C<STRING* Parrot_str_change_encoding(PARROT_INTERP, STRING *src, INTVAL
-encoding_nr, STRING *dest)>
+encoding_nr)>
 
-If C<dest> == NULL, converts C<src> to the given charset or encoding in place.
-Otherwise returns a copy of C<src> with the charset/encoding in C<dest>
+Converts C<src> to the given charset or encoding and returns the result as a
+new string.
 
 =cut
 
@@ -3337,7 +2901,7 @@
 PARROT_CAN_RETURN_NULL
 STRING*
 Parrot_str_change_encoding(PARROT_INTERP, ARGIN_NULLOK(STRING *src),
-        INTVAL encoding_nr, ARGOUT_NULLOK(STRING *dest))
+        INTVAL encoding_nr)
 {
     ASSERT_ARGS(Parrot_str_change_encoding)
     const ENCODING *new_encoding;
@@ -3351,25 +2915,10 @@
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_CHARTYPE,
             "encoding #%d not found", (int) encoding_nr);
 
-    /*
-     * dest is an empty string header or NULL, if an inplace
-     * operation is desired
-     */
-    if (!STRING_IS_NULL(dest)) {
-        dest->encoding = new_encoding;
-        if (new_encoding == src->encoding) {
-            dest = Parrot_str_reuse_COW(interp, src, dest);
-            return dest;
-        }
-    }
-    else {
-        if (new_encoding == src->encoding)
-            return src;
+    if (new_encoding == src->encoding)
+        return src;
 
-        Parrot_str_write_COW(interp, src);
-    }
-
-    return new_encoding->to_encoding(interp, src, dest);
+    return new_encoding->to_encoding(interp, src);
 }
 
 
@@ -3390,6 +2939,7 @@
 Parrot_str_compose(PARROT_INTERP, ARGIN_NULLOK(STRING *src))
 {
     ASSERT_ARGS(Parrot_str_compose)
+
     if (STRING_IS_NULL(src))
         return NULL;
 
@@ -3418,24 +2968,104 @@
 Parrot_str_join(PARROT_INTERP, ARGIN_NULLOK(STRING *j), ARGIN(PMC *ar))
 {
     ASSERT_ARGS(Parrot_str_join)
-    STRING *res;
-    STRING *s;
-    const int ar_len = VTABLE_elements(interp, ar);
-    int i;
+    STRING  **chunks;
+    STRING   *res;
+    STRING   *s;
+    char     *pos;
+    const int ar_len       = VTABLE_elements(interp, ar);
+    int       total_length = 0;
+    int       transcoded   = 0;
+    int       i;
 
     if (ar_len == 0)
         return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
 
-    s   = VTABLE_get_string_keyed_int(interp, ar, 0);
-    res = !STRING_IS_NULL(s) ? Parrot_str_copy(interp, s) : NULL;
+    if (STRING_IS_NULL(j))
+        j = Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
+
+    chunks = (STRING **)Parrot_gc_allocate_fixed_size_storage(interp,
+        ar_len * sizeof (STRING *));
+
+    for (i = 0; i < ar_len; ++i) {
+        STRING *next = VTABLE_get_string_keyed_int(interp, ar, i);
+
+        if (STRING_IS_NULL(next)) {
+            chunks[i] = STRINGNULL;
+            continue;
+        }
+
+        if (next->encoding != j->encoding) {
+            const ENCODING *e = j->encoding;
+            const CHARSET  *c = string_rep_compatible(interp, next, j, &e);
+            if (e == Parrot_fixed_8_encoding_ptr)
+                e = Parrot_utf8_encoding_ptr;
+            j           = e->to_encoding(interp, j);
+            transcoded  = 1;
+        }
+
+        chunks[i]     = next;
+        total_length += next->bufused;
+    }
+
+    /* with the right charset, transcode any strings if necessary*/
+    if (transcoded) {
+        const CHARSET  *c = j->charset;
+        const ENCODING *e = j->encoding;
+
+        for (i = 0; i < ar_len; ++i) {
+            STRING *s = chunks[i];
+
+            if (STRING_IS_NULL(s))
+                continue;
+
+            if (s->encoding != e || s->charset != c) {
+                STRING *new_s = e->to_encoding(interp, s);
+                chunks[i]     = new_s;
+                total_length += s->bufused - new_s->bufused;
+            }
+        }
+    }
+
+    /* add the length of the separator, now that it's transcoded */
+    total_length += j->bufused * ar_len;
+
+    res = Parrot_gc_new_string_header(interp, 0);
+    Parrot_gc_allocate_string_storage(interp, res, total_length);
+
+    res->charset  = j->charset;
+    res->encoding = j->encoding;
+
+    /* Iterate over chunks and append it to res */
+    pos = res->strstart;
+
+    /* Copy first chunk */
+    s = chunks[0];
+    if (!STRING_IS_NULL(s)) {
+        mem_sys_memcopy(pos, s->strstart, s->bufused);
+        pos += s->bufused;
+    }
 
     for (i = 1; i < ar_len; ++i) {
-        STRING * const next = VTABLE_get_string_keyed_int(interp, ar, i);
+        STRING *next = chunks[i];
+
+        if (STRING_IS_NULL(next))
+            continue;
 
-        res  = Parrot_str_append(interp, res, j);
-        res  = Parrot_str_append(interp, res, next);
+        mem_sys_memcopy(pos, j->strstart, j->bufused);
+        pos += j->bufused;
+
+        mem_sys_memcopy(pos, next->strstart, next->bufused);
+        pos += next->bufused;
+
+        PARROT_ASSERT(pos <= res->strstart + Buffer_buflen(res));
     }
 
+    res->bufused  = pos - res->strstart;
+    res->strlen = CHARSET_CODEPOINTS(interp, res);
+
+    Parrot_gc_free_fixed_size_storage(interp, ar_len * sizeof (STRING *),
+        chunks);
+
     return res;
 }
 
@@ -3445,8 +3075,8 @@
 =item C<PMC* Parrot_str_split(PARROT_INTERP, STRING *delim, STRING *str)>
 
 Splits the string C<str> at the delimiter C<delim>, returning a
-C<ResizableStringArray>, or his mapped type in the current HLL,
-of results. Returns PMCNULL if the string or the delimiter is NULL.
+C<ResizableStringArray>, or his mapped type in the current HLL, of results.
+Returns PMCNULL if the string or the delimiter is NULL.
 
 =cut
 
@@ -3466,7 +3096,8 @@
     if (STRING_IS_NULL(delim) || STRING_IS_NULL(str))
         return PMCNULL;
 
-    res  = Parrot_pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_ResizableStringArray));
+    res  = Parrot_pmc_new(interp,
+            Parrot_get_ctx_HLL_type(interp, enum_class_ResizableStringArray));
     slen = Parrot_str_byte_length(interp, str);
 
     if (!slen)
@@ -3479,7 +3110,7 @@
         VTABLE_set_integer_native(interp, res, slen);
 
         for (i = 0; i < slen; ++i) {
-            STRING * const p = Parrot_str_substr(interp, str, i, 1, NULL, 0);
+            STRING * const p = Parrot_str_substr(interp, str, i, 1);
             VTABLE_set_string_keyed_int(interp, res, i, p);
         }
 
@@ -3497,7 +3128,7 @@
 
     while (ps <= slen) {
         const int      pl   = pe - ps;
-        STRING * const tstr = Parrot_str_substr(interp, str, ps, pl, NULL, 0);
+        STRING * const tstr = Parrot_str_substr(interp, str, ps, pl);
 
         VTABLE_push_string(interp, res, tstr);
         ps = pe + Parrot_str_byte_length(interp, delim);
@@ -3539,6 +3170,7 @@
     unsigned int base, int minus)
 {
     ASSERT_ARGS(Parrot_str_from_uint)
+
     /* the buffer must be at least as long as this */
     char               *p    = tc + sizeof (UHUGEINTVAL)*8 + 1;
     const char * const  tail = p;
@@ -3547,12 +3179,12 @@
 
     do {
         const char cur = (char)(num % base);
-        if (cur < 10) {
+
+        if (cur < 10)
             *--p = (char)('0' + cur);
-        }
-        else {
+        else
             *--p = (char)('a' + cur - 10);
-        }
+
     } while (num /= base);
 
     if (minus)
@@ -3591,6 +3223,7 @@
     return Parrot_str_from_uint(interp, tc, (UHUGEINTVAL)num, base, is_neg);
 }
 
+
 /*
 
 =back

Modified: trunk/src/string/charset.c
==============================================================================
--- trunk/src/string/charset.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -29,16 +29,16 @@
 #include "charset/iso-8859-1.h"
 #include "charset/unicode.h"
 
-CHARSET *Parrot_iso_8859_1_charset_ptr;
-CHARSET *Parrot_binary_charset_ptr;
-CHARSET *Parrot_default_charset_ptr;
-CHARSET *Parrot_unicode_charset_ptr;
-CHARSET *Parrot_ascii_charset_ptr;
+const CHARSET *Parrot_iso_8859_1_charset_ptr;
+const CHARSET *Parrot_binary_charset_ptr;
+const CHARSET *Parrot_default_charset_ptr;
+const CHARSET *Parrot_unicode_charset_ptr;
+const CHARSET *Parrot_ascii_charset_ptr;
 
 /* all registered charsets are collected in one global structure */
 
 typedef struct To_converter {
-    NOTNULL(CHARSET *to);
+    NOTNULL(const CHARSET *to);
     NOTNULL(charset_converter_t func);
 } To_converter;
 
@@ -97,7 +97,7 @@
 */
 
 PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
+PARROT_CANNOT_RETURN_NULL
 PARROT_MALLOC
 CHARSET *
 Parrot_new_charset(PARROT_INTERP)
@@ -168,7 +168,8 @@
 
 /*
 
-=item C<CHARSET * Parrot_load_charset(PARROT_INTERP, const char *charsetname)>
+=item C<const CHARSET * Parrot_load_charset(PARROT_INTERP, const char
+*charsetname)>
 
 Throws an exception (Can't load charsets dynamically yet. https://trac.parrot.org/parrot/wiki/StringsTasklist).
 
@@ -179,7 +180,7 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-CHARSET *
+const CHARSET *
 Parrot_load_charset(PARROT_INTERP, ARGIN(const char *charsetname))
 {
     ASSERT_ARGS(Parrot_load_charset)
@@ -243,7 +244,7 @@
 
 /*
 
-=item C<STRING* Parrot_charset_name(PARROT_INTERP, INTVAL number_of_charset)>
+=item C<STRING * Parrot_charset_name(PARROT_INTERP, INTVAL number_of_charset)>
 
 Returns the name of the charset given by the INTVAL index
 C<number_of_charset>.
@@ -255,12 +256,12 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-STRING*
+STRING *
 Parrot_charset_name(SHIM_INTERP, INTVAL number_of_charset)
 {
     ASSERT_ARGS(Parrot_charset_name)
     if (number_of_charset < 0 || number_of_charset >= all_charsets->n_charsets)
-        return NULL;
+        return STRINGNULL;
     return all_charsets->set[number_of_charset].name;
 }
 
@@ -509,7 +510,7 @@
 /*
 
 =item C<INTVAL Parrot_make_default_charset(PARROT_INTERP, const char
-*charsetname, CHARSET *charset)>
+*charsetname, const CHARSET *charset)>
 
 Sets the current default charset to C<charset> with name C<charsetname>.
 
@@ -520,7 +521,7 @@
 PARROT_EXPORT
 INTVAL
 Parrot_make_default_charset(SHIM_INTERP, SHIM(const char *charsetname),
-        ARGIN(CHARSET *charset))
+        ARGIN(const CHARSET *charset))
 {
     ASSERT_ARGS(Parrot_make_default_charset)
     Parrot_default_charset_ptr = charset;
@@ -587,7 +588,7 @@
 /*
 
 =item C<void Parrot_register_charset_converter(PARROT_INTERP, const CHARSET
-*lhs, CHARSET *rhs, charset_converter_t func)>
+*lhs, const CHARSET *rhs, charset_converter_t func)>
 
 Registers a converter C<func> from charset C<lhs> to C<rhs>.
 
@@ -598,7 +599,7 @@
 PARROT_EXPORT
 void
 Parrot_register_charset_converter(PARROT_INTERP,
-        ARGIN(const CHARSET *lhs), ARGIN(CHARSET *rhs),
+        ARGIN(const CHARSET *lhs), ARGIN(const CHARSET *rhs),
         ARGIN(charset_converter_t func))
 {
     ASSERT_ARGS(Parrot_register_charset_converter)

Modified: trunk/src/string/charset/ascii.c
==============================================================================
--- trunk/src/string/charset/ascii.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/ascii.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2004-2009, Parrot Foundation.
+Copyright (C) 2004-2010, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -42,10 +42,15 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*src);
 
-static void downcase(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase(PARROT_INTERP, ARGIN(const STRING *source_string))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void downcase_first(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase_first(PARROT_INTERP,
+    ARGIN(const STRING *source_string))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
@@ -73,56 +78,41 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-static void set_graphemes(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL replace_count,
-    ARGMOD(STRING *insert_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*insert_string);
-
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 static STRING * string_from_codepoint(PARROT_INTERP, UINTVAL codepoint)
         __attribute__nonnull__(1);
 
-static void titlecase(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase(PARROT_INTERP, ARGIN(const STRING *source_string))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void titlecase_first(SHIM_INTERP, ARGMOD(STRING *source_string))
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*source_string);
-
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_ascii(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGMOD_NULLOK(STRING *dest))
+static STRING* titlecase_first(PARROT_INTERP,
+    ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_charset(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+static STRING * to_ascii(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_unicode(PARROT_INTERP,
-    ARGMOD(STRING *src),
-    ARGMOD_NULLOK(STRING *dest))
+static STRING * to_charset(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*src)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
-static void upcase(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase(PARROT_INTERP, ARGIN(const STRING *source_string))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void upcase_first(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase_first(PARROT_INTERP,
+    ARGIN(const STRING *source_string))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
@@ -137,9 +127,11 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_downcase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(source_string))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_downcase_first __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(source_string))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_find_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
@@ -149,29 +141,26 @@
 #define ASSERT_ARGS_is_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_set_graphemes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(insert_string))
 #define ASSERT_ARGS_string_from_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_titlecase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(source_string))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_titlecase_first __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(source_string))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_to_ascii __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_to_charset __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_to_unicode __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_upcase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(source_string))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_upcase_first __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(source_string))
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_validate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
@@ -202,53 +191,7 @@
 
 /*
 
-=item C<static void set_graphemes(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL replace_count, STRING *insert_string)>
-
-Sets the graphemes for C<source_string>, starting at C<offset>. Replace
-C<replace_count> graphemes with those from STRING C<insert_string>.
-
-=cut
-
-*/
-
-static void
-set_graphemes(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL replace_count, ARGMOD(STRING *insert_string))
-{
-    ASSERT_ARGS(set_graphemes)
-    ENCODING_SET_BYTES(interp, source_string, offset,
-            replace_count, insert_string);
-
-}
-
-/*
-
-=item C<STRING * ascii_get_graphemes_inplace(PARROT_INTERP, STRING
-*source_string, UINTVAL offset, UINTVAL count, STRING *dest_string)>
-
-Retrieves the graphemes in place for ascii STRING C<source_string>,
-starting at C<offset>. Retrieves C<count> graphemes and puts them
-into C<dest_string>.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-STRING *
-ascii_get_graphemes_inplace(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *dest_string))
-{
-    ASSERT_ARGS(ascii_get_graphemes_inplace)
-    return ENCODING_GET_BYTES_INPLACE(interp, source_string,
-            offset, count, dest_string);
-}
-
-/*
-
-=item C<static STRING * to_ascii(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_ascii(PARROT_INTERP, STRING *src)>
 
 Attempts to convert STRING C<src> to ASCII in STRING C<dest>. Throws
 an exception if unconvertable UNICODE characters are involved.
@@ -259,7 +202,7 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_ascii(PARROT_INTERP, ARGIN(STRING *src), ARGMOD_NULLOK(STRING *dest))
+to_ascii(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_ascii)
     String_iter iter;
@@ -267,13 +210,9 @@
     unsigned char *p;
     const UINTVAL len = src->strlen;
 
-    if (dest) {
-        Parrot_gc_reallocate_string_storage(interp, dest, len);
-    }
-    else {
-        /* the string can't grow - replace inplace */
-        dest = src;
-    }
+    /* the string can't grow. Just clone it */
+    STRING * dest = Parrot_str_clone(interp, src);
+
     p = (unsigned char *)dest->strstart;
     ENCODING_ITER_INIT(interp, src, &iter);
     for (offs = 0; offs < len; ++offs) {
@@ -292,35 +231,7 @@
 
 /*
 
-=item C<static STRING * to_unicode(PARROT_INTERP, STRING *src, STRING *dest)>
-
-Converts the ASCII STRING C<src> to UNICODE STRING C<dest>.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-to_unicode(PARROT_INTERP, ARGMOD(STRING *src), ARGMOD_NULLOK(STRING *dest))
-{
-    ASSERT_ARGS(to_unicode)
-    if (dest) {
-        dest->charset = Parrot_unicode_charset_ptr;
-        dest->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, dest);
-        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
-        return dest;
-    }
-    else {
-        src->charset = Parrot_unicode_charset_ptr;
-        src->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, src);
-        return src;
-    }
-}
-
-/*
-
-=item C<static STRING * to_charset(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_charset(PARROT_INTERP, STRING *src)>
 
 Converts STRING C<src> to ASCII charset STRING C<dest>.
 
@@ -330,17 +241,17 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_charset(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
+to_charset(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_charset)
     const charset_converter_t conversion_func =
         Parrot_find_charset_converter(interp, src->charset, Parrot_ascii_charset_ptr);
 
     if (conversion_func) {
-         return conversion_func(interp, src, dest);
+         return conversion_func(interp, src);
     }
     else {
-        return to_ascii(interp, src, dest);
+        return to_ascii(interp, src);
     }
 }
 
@@ -361,7 +272,7 @@
 compose(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(compose)
-    return Parrot_str_copy(interp, src);
+    return src;
 }
 
 /* A noop. can't decompose ascii */
@@ -381,12 +292,12 @@
 decompose(PARROT_INTERP, ARGMOD(STRING *src))
 {
     ASSERT_ARGS(decompose)
-    return Parrot_str_copy(interp, src);
+    return src;
 }
 
 /*
 
-=item C<static void upcase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase(PARROT_INTERP, const STRING *source_string)>
 
 Converts the STRING C<source_string> to all uppercase.
 
@@ -394,25 +305,29 @@
 
 */
 
-static void
-upcase(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(upcase)
+    STRING * const result = Parrot_str_clone(interp, source_string);
     const UINTVAL n = source_string->strlen;
 
     if (n) {
-        char * const buffer = source_string->strstart;
+        char * const buffer = result->strstart;
         UINTVAL offset;
 
         for (offset = 0; offset < n; offset++) {
             buffer[offset] = (char)toupper((unsigned char)buffer[offset]);
         }
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void downcase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase(PARROT_INTERP, const STRING *source_string)>
 
 Converts the STRING C<source_string> to all lower-case.
 
@@ -420,25 +335,29 @@
 
 */
 
-static void
-downcase(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(downcase)
-    const UINTVAL n = source_string->strlen;
+    STRING       *result = Parrot_str_clone(interp, source_string);
+    const UINTVAL n      = source_string->strlen;
 
     if (n) {
-        char * const buffer = source_string->strstart;
+        char * const buffer = result->strstart;
         UINTVAL offset;
 
         for (offset = 0; offset < n; offset++) {
             buffer[offset] = (char)tolower((unsigned char)buffer[offset]);
         }
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void titlecase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase(PARROT_INTERP, const STRING *source_string)>
 
 Converts the STRING given by C<source_string> to title case, where
 the first character is upper case and all the rest of the characters
@@ -448,14 +367,16 @@
 
 */
 
-static void
-titlecase(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase)
-    const UINTVAL n = source_string->strlen;
+    STRING       *result = Parrot_str_clone(interp, source_string);
+    const UINTVAL n      = source_string->strlen;
 
     if (n) {
-        char * const buffer = source_string->strstart;
+        char * const buffer = result->strstart;
         UINTVAL offset;
 
         buffer[0] = (char)toupper((unsigned char)buffer[0]);
@@ -463,11 +384,13 @@
             buffer[offset] = (char)tolower((unsigned char)buffer[offset]);
         }
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void upcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase_first(PARROT_INTERP, const STRING *source_string)>
 
 Sets the first character in the STRING C<source_string> to upper case,
 but doesn't modify the rest of the string.
@@ -476,19 +399,25 @@
 
 */
 
-static void
-upcase_first(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase_first(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(upcase_first)
-    if (source_string->strlen) {
-        char * const buffer = source_string->strstart;
+    STRING *result = Parrot_str_clone(interp, source_string);
+
+    if (result->strlen) {
+        char * const buffer = result->strstart;
         buffer[0] = (char)toupper((unsigned char)buffer[0]);
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void downcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Sets the first character of the STRING C<source_string> to lowercase,
 but doesn't modify the rest of the characters.
@@ -497,19 +426,25 @@
 
 */
 
-static void
-downcase_first(SHIM_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase_first(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(downcase_first)
-    if (source_string->strlen) {
-        char * const buffer = source_string->strstart;
+    STRING *result = Parrot_str_clone(interp, source_string);
+
+    if (result->strlen) {
+        char * const buffer = result->strstart;
         buffer[0] = (char)tolower((unsigned char)buffer[0]);
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void titlecase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Converts the first letter of STRING C<source_string> to upper case,
 but doesn't modify the rest of the string.
@@ -518,14 +453,19 @@
 
 */
 
-static void
-titlecase_first(SHIM_INTERP, ARGMOD(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase_first(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase_first)
-    if (source_string->strlen) {
-        char * const buffer = source_string->strstart;
+    STRING *result = Parrot_str_clone(interp, source_string);
+
+    if (result->strlen) {
+        char * const buffer = result->strstart;
         buffer[0] = (char)toupper((unsigned char)buffer[0]);
     }
+
+    return result;
 }
 
 /*
@@ -550,8 +490,7 @@
     const UINTVAL min_len = l_len > r_len ? r_len : l_len;
     String_iter iter;
 
-    if (lhs->encoding == Parrot_fixed_8_encoding_ptr &&
-            rhs->encoding == Parrot_fixed_8_encoding_ptr) {
+    if (lhs->encoding == rhs->encoding) {
         const int ret_val = memcmp(lhs->strstart, rhs->strstart, min_len);
         if (ret_val)
             return ret_val < 0 ? -1 : 1;
@@ -856,7 +795,7 @@
 
 /*
 
-=item C<const CHARSET * Parrot_charset_ascii_init(PARROT_INTERP)>
+=item C<void Parrot_charset_ascii_init(PARROT_INTERP)>
 
 Initialize the ASCII charset but registering all the necessary
 function pointers and settings.
@@ -865,8 +804,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET *
+void
 Parrot_charset_ascii_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_charset_ascii_init)
@@ -874,8 +812,6 @@
     static const CHARSET base_set = {
         "ascii",
         ascii_get_graphemes,
-        ascii_get_graphemes_inplace,
-        set_graphemes,
         to_charset,
         compose,
         decompose,
@@ -900,13 +836,13 @@
     STRUCT_COPY_FROM_STRUCT(return_set, base_set);
     return_set->preferred_encoding = Parrot_fixed_8_encoding_ptr;
     Parrot_register_charset(interp, "ascii", return_set);
-    return return_set;
+
+    return;
 }
 
 /*
 
-=item C<STRING * charset_cvt_ascii_to_binary(PARROT_INTERP, STRING *src, STRING
-*dest)>
+=item C<STRING * charset_cvt_ascii_to_binary(PARROT_INTERP, STRING *src)>
 
 Converts an ASCII STRING C<src> to a binary STRING C<dest>.
 
@@ -916,29 +852,24 @@
 
 PARROT_CANNOT_RETURN_NULL
 STRING *
-charset_cvt_ascii_to_binary(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
+charset_cvt_ascii_to_binary(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(charset_cvt_ascii_to_binary)
-    if (dest) {
-        UINTVAL offs;
+    STRING *dest = Parrot_str_clone(interp, src);
+    UINTVAL offs;
 
-        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
-        dest->bufused = src->bufused;
-        dest->strlen  = src->strlen;
-        for (offs = 0; offs < src->strlen; ++offs) {
-            const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
-            ENCODING_SET_BYTE(interp, dest, offs, c);
-        }
-        return dest;
+    for (offs = 0; offs < src->strlen; ++offs) {
+        const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
+        ENCODING_SET_BYTE(interp, dest, offs, c);
     }
-    src->charset = Parrot_binary_charset_ptr;
-    return src;
+
+    dest->charset = Parrot_binary_charset_ptr;
+    return dest;
 }
 
 /*
 
-=item C<STRING * charset_cvt_ascii_to_iso_8859_1(PARROT_INTERP, STRING *src,
-STRING *dest)>
+=item C<STRING * charset_cvt_ascii_to_iso_8859_1(PARROT_INTERP, STRING *src)>
 
 Converts ASCII STRING C<src> to ISO8859-1 STRING C<dest>.
 
@@ -948,24 +879,19 @@
 
 PARROT_CANNOT_RETURN_NULL
 STRING *
-charset_cvt_ascii_to_iso_8859_1(PARROT_INTERP, ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+charset_cvt_ascii_to_iso_8859_1(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(charset_cvt_ascii_to_iso_8859_1)
-    if (dest) {
-        UINTVAL offs;
+    STRING * dest = Parrot_str_clone(interp, src);
+    UINTVAL offs;
 
-        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
-        dest->bufused = src->bufused;
-        dest->strlen  = src->strlen;
-        for (offs = 0; offs < src->strlen; ++offs) {
-            const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
-            ENCODING_SET_BYTE(interp, dest, offs, c);
-        }
-        return dest;
+    for (offs = 0; offs < src->strlen; ++offs) {
+        const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
+        ENCODING_SET_BYTE(interp, dest, offs, c);
     }
-    src->charset = Parrot_iso_8859_1_charset_ptr;
-    return src;
+
+    dest->charset = Parrot_iso_8859_1_charset_ptr;
+    return dest;
 }
 
 /*

Modified: trunk/src/string/charset/ascii.h
==============================================================================
--- trunk/src/string/charset/ascii.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/ascii.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -61,29 +61,13 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-STRING * ascii_get_graphemes_inplace(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *dest_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*dest_string);
-
 PARROT_CANNOT_RETURN_NULL
-STRING * charset_cvt_ascii_to_binary(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+STRING * charset_cvt_ascii_to_binary(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
-STRING * charset_cvt_ascii_to_iso_8859_1(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+STRING * charset_cvt_ascii_to_iso_8859_1(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -96,8 +80,7 @@
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET * Parrot_charset_ascii_init(PARROT_INTERP)
+void Parrot_charset_ascii_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_ascii_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -117,10 +100,6 @@
 #define ASSERT_ARGS_ascii_get_graphemes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_ascii_get_graphemes_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(dest_string))
 #define ASSERT_ARGS_charset_cvt_ascii_to_binary __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))

Modified: trunk/src/string/charset/binary.c
==============================================================================
--- trunk/src/string/charset/binary.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/binary.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -51,10 +51,13 @@
 static STRING* decompose(PARROT_INTERP, SHIM(STRING *source_string))
         __attribute__nonnull__(1);
 
-static void downcase(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase(PARROT_INTERP, SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
-static void downcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase_first(PARROT_INTERP,
+    SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
 static INTVAL find_cclass(SHIM_INTERP,
@@ -74,37 +77,31 @@
     SHIM(const STRING *source_string),
     SHIM(UINTVAL offset));
 
-static void set_graphemes(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL replace_count,
-    ARGMOD(STRING *insert_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*insert_string);
-
 PARROT_CANNOT_RETURN_NULL
 static STRING * string_from_codepoint(PARROT_INTERP, UINTVAL codepoint)
         __attribute__nonnull__(1);
 
-static void titlecase(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase(PARROT_INTERP, SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
-static void titlecase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase_first(PARROT_INTERP,
+    SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING* to_charset(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+static STRING* to_charset(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void upcase(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase(PARROT_INTERP, SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
-static void upcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase_first(PARROT_INTERP,
+    SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
 static UINTVAL validate(SHIM_INTERP, SHIM(STRING *source_string));
@@ -124,10 +121,6 @@
 #define ASSERT_ARGS_find_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_find_not_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_is_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_set_graphemes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(insert_string))
 #define ASSERT_ARGS_string_from_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_titlecase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -152,31 +145,10 @@
 #define EXCEPTION(err, str) \
     Parrot_ex_throw_from_c_args(interp, NULL, (err), (str))
 
-/*
-
-=item C<static void set_graphemes(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL replace_count, STRING *insert_string)>
-
-Sets the graphemes for STRING C<source_string>, starting at offset
-C<offset>. Replaces C<replace_count> graphemes from STRING
-C<insert_string>.
-
-=cut
-
-*/
-
-static void
-set_graphemes(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL replace_count, ARGMOD(STRING *insert_string))
-{
-    ASSERT_ARGS(set_graphemes)
-    ENCODING_SET_BYTES(interp, source_string, offset,
-            replace_count, insert_string);
-}
 
 /*
 
-=item C<static STRING* to_charset(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING* to_charset(PARROT_INTERP, STRING *src)>
 
 Converts the STRING C<src> to STRING C<dest> in binary mode. Throws
 an exception if a suitable conversion function is not found.
@@ -187,14 +159,14 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING*
-to_charset(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
+to_charset(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_charset)
     charset_converter_t conversion_func =
         Parrot_find_charset_converter(interp, src->charset, Parrot_binary_charset_ptr);
 
     if (conversion_func)
-         return conversion_func(interp, src, dest);
+         return conversion_func(interp, src);
 
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
         "to_charset for binary not implemented");
@@ -240,7 +212,7 @@
 
 /*
 
-=item C<static void upcase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase(PARROT_INTERP, const STRING *source_string)>
 
 Throws an exception because we cannot convert a binary string to
 upper case.
@@ -249,8 +221,9 @@
 
 */
 
-static void
-upcase(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(upcase)
     EXCEPTION(EXCEPTION_INVALID_CHARTYPE, "Can't upcase binary data");
@@ -258,7 +231,7 @@
 
 /*
 
-=item C<static void downcase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase(PARROT_INTERP, const STRING *source_string)>
 
 Throws an exception because we cannot convert a binary string to
 lower-case.
@@ -267,8 +240,9 @@
 
 */
 
-static void
-downcase(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(downcase)
     EXCEPTION(EXCEPTION_INVALID_CHARTYPE, "Can't downcase binary data");
@@ -276,7 +250,7 @@
 
 /*
 
-=item C<static void titlecase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase(PARROT_INTERP, const STRING *source_string)>
 
 Throws an exception because we cannot convert a binary string to
 title case.
@@ -285,8 +259,9 @@
 
 */
 
-static void
-titlecase(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase)
     EXCEPTION(EXCEPTION_INVALID_CHARTYPE, "Can't titlecase binary data");
@@ -294,7 +269,7 @@
 
 /*
 
-=item C<static void upcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase_first(PARROT_INTERP, const STRING *source_string)>
 
 Throws an exception because we cannot set the first "character" of the
 binary string to uppercase.
@@ -303,8 +278,9 @@
 
 */
 
-static void
-upcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase_first(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(upcase_first)
     EXCEPTION(EXCEPTION_INVALID_CHARTYPE, "Can't upcase binary data");
@@ -312,7 +288,8 @@
 
 /*
 
-=item C<static void downcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Throws an exception because we cannot set the first "character"
 of the binary string to lowercase.
@@ -321,8 +298,9 @@
 
 */
 
-static void
-downcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase_first(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(downcase_first)
     EXCEPTION(EXCEPTION_INVALID_CHARTYPE, "Can't downcase binary data");
@@ -330,7 +308,8 @@
 
 /*
 
-=item C<static void titlecase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Throws an exception because we can't convert the first "character"
 of binary data to title case.
@@ -339,8 +318,9 @@
 
 */
 
-static void
-titlecase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase_first(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase_first)
     EXCEPTION(EXCEPTION_INVALID_CHARTYPE, "Can't titlecase binary data");
@@ -500,7 +480,7 @@
 
 /*
 
-=item C<const CHARSET * Parrot_charset_binary_init(PARROT_INTERP)>
+=item C<void Parrot_charset_binary_init(PARROT_INTERP)>
 
 Initialize the binary charset, including function pointers and
 settings.
@@ -509,8 +489,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET *
+void
 Parrot_charset_binary_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_charset_binary_init)
@@ -518,8 +497,6 @@
     static const CHARSET base_set = {
         "binary",
         ascii_get_graphemes,
-        ascii_get_graphemes_inplace,
-        set_graphemes,
         to_charset,
         compose,
         decompose,
@@ -544,7 +521,8 @@
     STRUCT_COPY_FROM_STRUCT(return_set, base_set);
     return_set->preferred_encoding = Parrot_fixed_8_encoding_ptr;
     Parrot_register_charset(interp, "binary", return_set);
-    return return_set;
+
+    return;
 
 }
 

Modified: trunk/src/string/charset/binary.h
==============================================================================
--- trunk/src/string/charset/binary.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/binary.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -16,8 +16,7 @@
 /* HEADERIZER BEGIN: src/string/charset/binary.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET * Parrot_charset_binary_init(PARROT_INTERP)
+void Parrot_charset_binary_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_Parrot_charset_binary_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/string/charset/iso-8859-1.c
==============================================================================
--- trunk/src/string/charset/iso-8859-1.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/iso-8859-1.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -35,11 +35,14 @@
 static STRING* decompose(PARROT_INTERP, SHIM(STRING *src))
         __attribute__nonnull__(1);
 
-static void downcase(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase(PARROT_INTERP, ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void downcase_first(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase_first(PARROT_INTERP,
+    ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -66,57 +69,45 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-static void set_graphemes(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL replace_count,
-    ARGMOD(STRING *insert_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*insert_string);
-
 PARROT_CANNOT_RETURN_NULL
 static STRING * string_from_codepoint(PARROT_INTERP, UINTVAL codepoint)
         __attribute__nonnull__(1);
 
-static void titlecase(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase(PARROT_INTERP, ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void titlecase_first(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase_first(PARROT_INTERP,
+    ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-static STRING * to_charset(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+static STRING * to_charset(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_iso_8859_1(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGMOD_NULLOK(STRING *dest))
+static STRING * to_iso_8859_1(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_unicode(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGMOD_NULLOK(STRING *dest))
+static STRING * to_unicode(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
-static void upcase(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase(PARROT_INTERP, ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void upcase_first(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase_first(PARROT_INTERP,
+    ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -144,10 +135,6 @@
 #define ASSERT_ARGS_is_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_set_graphemes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(insert_string))
 #define ASSERT_ARGS_string_from_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_titlecase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -181,28 +168,7 @@
 
 /*
 
-=item C<static void set_graphemes(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL replace_count, STRING *insert_string)>
-
-Sets C<replace_count> graphemes in STRING C<source_string> starting at offset C<offset>.
-Gets the replacement graphemes from STRING C<insert_string>.
-
-=cut
-
-*/
-
-static void
-set_graphemes(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL replace_count, ARGMOD(STRING *insert_string))
-{
-    ASSERT_ARGS(set_graphemes)
-    ENCODING_SET_BYTES(interp, source_string, offset,
-            replace_count, insert_string);
-}
-
-/*
-
-=item C<static STRING * to_iso_8859_1(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_iso_8859_1(PARROT_INTERP, STRING *src)>
 
 Converts STRING C<src> to iso-8859-1 in STRING C<dest>.
 
@@ -212,22 +178,16 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_iso_8859_1(PARROT_INTERP, ARGIN(STRING *src), ARGMOD_NULLOK(STRING *dest))
+to_iso_8859_1(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_iso_8859_1)
     UINTVAL offs, src_len;
     String_iter iter;
+    /* iso-8859-1 is never bigger then source */
+    STRING * dest = Parrot_str_clone(interp, src);
 
     ENCODING_ITER_INIT(interp, src, &iter);
     src_len = src->strlen;
-    if (dest) {
-        Parrot_gc_reallocate_string_storage(interp, dest, src_len);
-        dest->strlen  = src_len;
-    }
-    else {
-        /* iso-8859-1 is never bigger then source */
-        dest = src;
-    }
     dest->bufused = src_len;
     dest->charset = Parrot_iso_8859_1_charset_ptr;
     dest->encoding = Parrot_fixed_8_encoding_ptr;
@@ -244,7 +204,7 @@
 
 /*
 
-=item C<static STRING * to_unicode(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_unicode(PARROT_INTERP, STRING *src)>
 
 Converts STRING C<src> to unicode STRING C<dest>.
 
@@ -254,40 +214,37 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_unicode(PARROT_INTERP, ARGIN(STRING *src), ARGMOD_NULLOK(STRING *dest))
+to_unicode(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_unicode)
-    if (dest) {
-        UINTVAL offs;
-        String_iter iter;
-
-        dest->charset = Parrot_unicode_charset_ptr;
-        dest->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, dest);
-        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
-        ENCODING_ITER_INIT(interp, dest, &iter);
-        for (offs = 0; offs < src->strlen; ++offs) {
-            const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
-
-            if (iter.bytepos >= Buffer_buflen(dest) - 4) {
-                UINTVAL need = (UINTVAL)((src->strlen - offs) * 1.5);
-                if (need < 16)
-                    need = 16;
-                Parrot_gc_reallocate_string_storage(interp, dest,
-                        Buffer_buflen(dest) + need);
-            }
-            iter.set_and_advance(interp, &iter, c);
+    STRING * dest = Parrot_str_clone(interp, src);
+    UINTVAL offs;
+    String_iter iter;
+
+    dest->charset = Parrot_unicode_charset_ptr;
+    dest->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, dest);
+    Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
+    ENCODING_ITER_INIT(interp, dest, &iter);
+    for (offs = 0; offs < src->strlen; ++offs) {
+        const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
+
+        if (iter.bytepos >= Buffer_buflen(dest) - 4) {
+            UINTVAL need = (UINTVAL)((src->strlen - offs) * 1.5);
+            if (need < 16)
+                need = 16;
+            Parrot_gc_reallocate_string_storage(interp, dest,
+                    Buffer_buflen(dest) + need);
         }
-        dest->bufused = iter.bytepos;
-        dest->strlen  = iter.charpos;
-        return dest;
+        iter.set_and_advance(interp, &iter, c);
     }
-    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
-            "to_unicode inplace for iso-8859-1 not implemented");
+    dest->bufused = iter.bytepos;
+    dest->strlen  = iter.charpos;
+    return dest;
 }
 
 /*
 
-=item C<static STRING * to_charset(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_charset(PARROT_INTERP, STRING *src)>
 
 Converts the STRING C<src> to an ISO-8859-1 STRING C<dest>.
 
@@ -298,16 +255,16 @@
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 static STRING *
-to_charset(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
+to_charset(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_charset)
     const charset_converter_t conversion_func =
         Parrot_find_charset_converter(interp, src->charset, Parrot_iso_8859_1_charset_ptr);
 
     if (conversion_func)
-        return conversion_func(interp, src, dest);
+        return conversion_func(interp, src);
     else
-        return to_iso_8859_1(interp, src, dest);
+        return to_iso_8859_1(interp, src);
 }
 
 
@@ -329,7 +286,7 @@
 compose(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(compose)
-    return Parrot_str_copy(interp, src);
+    return src;
 }
 
 /*
@@ -353,7 +310,7 @@
 
 /*
 
-=item C<static void upcase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase(PARROT_INTERP, const STRING *source_string)>
 
 Convert all graphemes in the STRING C<source_string> to upper case, for those
 graphemes that support cases.
@@ -362,19 +319,20 @@
 
 */
 
-static void
-upcase(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(upcase)
     unsigned char *buffer;
-    UINTVAL offset = 0;
+    UINTVAL        offset = 0;
+    STRING        *result = Parrot_str_clone(interp, source_string);
 
-    if (!source_string->strlen)
-        return;
+    if (!result->strlen)
+        return result;
 
-    Parrot_str_write_COW(interp, source_string);
-    buffer = (unsigned char *)source_string->strstart;
-    for (offset = 0; offset < source_string->strlen; offset++) {
+    buffer = (unsigned char *)result->strstart;
+    for (offset = 0; offset < result->strlen; offset++) {
         unsigned int c = buffer[offset]; /* XXX use encoding ? */
         if (c >= 0xe0 && c != 0xf7)
             c &= ~0x20;
@@ -382,11 +340,13 @@
             c = toupper((unsigned char)c);
         buffer[offset] = (unsigned char)c;
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void downcase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase(PARROT_INTERP, const STRING *source_string)>
 
 Converts all graphemes in STRING C<source_string> to lower-case, for those graphemes
 that support cases.
@@ -395,30 +355,34 @@
 
 */
 
-static void
-downcase(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(downcase)
-    if (source_string->strlen) {
-        UINTVAL offset;
-        unsigned char *buffer;
-
-        Parrot_str_write_COW(interp, source_string);
-        buffer = (unsigned char *)source_string->strstart;
-        for (offset = 0; offset < source_string->strlen; offset++) {
-            unsigned int c = buffer[offset];
-            if (c >= 0xc0 && c != 0xd7 && c <= 0xde)
-                c |= 0x20;
-            else
-                c = tolower((unsigned char)c);
-            buffer[offset] = (unsigned char)c;
-        }
+    unsigned char *buffer;
+    UINTVAL        offset = 0;
+    STRING        *result = Parrot_str_clone(interp, source_string);
+
+    if (!result->strlen)
+        return result;
+
+    buffer = (unsigned char *)result->strstart;
+    for (offset = 0; offset < result->strlen; offset++) {
+        unsigned int c = buffer[offset];
+        if (c >= 0xc0 && c != 0xd7 && c <= 0xde)
+            c |= 0x20;
+        else
+            c = tolower((unsigned char)c);
+        buffer[offset] = (unsigned char)c;
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void titlecase(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase(PARROT_INTERP, const STRING *source_string)>
 
 Converts the graphemes in STRING C<source_string> to title case, for those graphemes
 that support cases.
@@ -427,19 +391,20 @@
 
 */
 
-static void
-titlecase(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase)
     unsigned char *buffer;
-    unsigned int c;
-    UINTVAL offset;
+    unsigned int   c;
+    UINTVAL        offset;
+    STRING        *result = Parrot_str_clone(interp, source_string);
 
-    if (!source_string->strlen)
-        return;
+    if (!result->strlen)
+        return result;
 
-    Parrot_str_write_COW(interp, source_string);
-    buffer = (unsigned char *)source_string->strstart;
+    buffer = (unsigned char *)result->strstart;
     c = buffer[0];
     if (c >= 0xe0 && c != 0xf7)
         c &= ~0x20;
@@ -447,7 +412,7 @@
         c = toupper((unsigned char)c);
     buffer[0] = (unsigned char)c;
 
-    for (offset = 1; offset < source_string->strlen; offset++) {
+    for (offset = 1; offset < result->strlen; offset++) {
         c = buffer[offset];
         if (c >= 0xc0 && c != 0xd7 && c <= 0xde)
             c |= 0x20;
@@ -455,11 +420,13 @@
             c = tolower((unsigned char)c);
         buffer[offset] = (unsigned char)c;
     }
+
+    return result;
 }
 
 /*
 
-=item C<static void upcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase_first(PARROT_INTERP, const STRING *source_string)>
 
 Converts the first grapheme in STRING C<source_string> to upper case, if it
 supports cases.
@@ -468,28 +435,33 @@
 
 */
 
-static void
-upcase_first(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase_first(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(upcase_first)
-    if (source_string->strlen) {
-        unsigned char *buffer;
-        unsigned int c;
-
-        Parrot_str_write_COW(interp, source_string);
-        buffer = (unsigned char *)source_string->strstart;
-        c = buffer[0];
-        if (c >= 0xe0 && c != 0xf7)
-            c &= ~0x20;
-        else
-            c = toupper((unsigned char)c);
-        buffer[0] = (unsigned char)c;
-    }
+    unsigned char *buffer;
+    unsigned int   c;
+    STRING        *result = Parrot_str_clone(interp, source_string);
+
+    if (!result->strlen)
+        return result;
+
+    buffer = (unsigned char *)result->strstart;
+    c = buffer[0];
+    if (c >= 0xe0 && c != 0xf7)
+        c &= ~0x20;
+    else
+        c = toupper((unsigned char)c);
+    buffer[0] = (unsigned char)c;
+
+    return result;
 }
 
 /*
 
-=item C<static void downcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Converts the first character of the STRING C<source_string> to lower case, if the
 grapheme supports lower case.
@@ -498,28 +470,33 @@
 
 */
 
-static void
-downcase_first(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase_first(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(downcase_first)
-    if (source_string->strlen) {
-        unsigned char *buffer;
-        unsigned int c;
-
-        Parrot_str_write_COW(interp, source_string);
-        buffer = (unsigned char *)source_string->strstart;
-        c = buffer[0];
-        if (c >= 0xc0 && c != 0xd7 && c <= 0xde)
-            c &= ~0x20;
-        else
-            c = tolower((unsigned char)c);
-        buffer[0] = (unsigned char)c;
-    }
+    unsigned char *buffer;
+    unsigned int   c;
+    STRING        *result = Parrot_str_clone(interp, source_string);
+
+    if (!result->strlen)
+        return result;
+
+    buffer = (unsigned char *)result->strstart;
+    c = buffer[0];
+    if (c >= 0xc0 && c != 0xd7 && c <= 0xde)
+        c &= ~0x20;
+    else
+        c = tolower((unsigned char)c);
+    buffer[0] = (unsigned char)c;
+
+    return result;
 }
 
 /*
 
-=item C<static void titlecase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Converts the first grapheme in STRING C<source_string> to title case, if the grapheme
 supports case.
@@ -528,11 +505,12 @@
 
 */
 
-static void
-titlecase_first(PARROT_INTERP, ARGIN(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase_first(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase_first)
-    upcase_first(interp, source_string);
+    return upcase_first(interp, source_string);
 }
 
 
@@ -662,7 +640,7 @@
 
 /*
 
-=item C<const CHARSET * Parrot_charset_iso_8859_1_init(PARROT_INTERP)>
+=item C<void Parrot_charset_iso_8859_1_init(PARROT_INTERP)>
 
 Initializes the ISO-8859-1 charset by installing all the necessary function pointers.
 
@@ -670,8 +648,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET *
+void
 Parrot_charset_iso_8859_1_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_charset_iso_8859_1_init)
@@ -679,8 +656,6 @@
     static const CHARSET base_set = {
         "iso-8859-1",
         ascii_get_graphemes,
-        ascii_get_graphemes_inplace,
-        set_graphemes,
         to_charset,
         compose,
         decompose,
@@ -705,13 +680,13 @@
     STRUCT_COPY_FROM_STRUCT(return_set, base_set);
     return_set->preferred_encoding = Parrot_fixed_8_encoding_ptr;
     Parrot_register_charset(interp, "iso-8859-1", return_set);
-    return return_set;
+
+    return;
 }
 
 /*
 
-=item C<STRING * charset_cvt_iso_8859_1_to_ascii(PARROT_INTERP, STRING *src,
-STRING *dest)>
+=item C<STRING * charset_cvt_iso_8859_1_to_ascii(PARROT_INTERP, STRING *src)>
 
 Converts STRING C<src> in ISO-8859-1 to ASCII STRING C<dest>.
 
@@ -722,29 +697,21 @@
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING *
-charset_cvt_iso_8859_1_to_ascii(PARROT_INTERP, ARGIN(STRING *src),
-        ARGMOD_NULLOK(STRING *dest))
+charset_cvt_iso_8859_1_to_ascii(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(charset_cvt_iso_8859_1_to_ascii)
     UINTVAL offs;
-    if (dest) {
-        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
-        dest->bufused = src->bufused;
-        dest->strlen  = src->strlen;
-    }
+    STRING *dest = Parrot_str_clone(interp, src);
+
     for (offs = 0; offs < src->strlen; ++offs) {
         UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
         if (c >= 0x80)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LOSSY_CONVERSION,
                 "lossy conversion to ascii");
 
-        if (dest)
-            ENCODING_SET_BYTE(interp, dest, offs, c);
+        ENCODING_SET_BYTE(interp, dest, offs, c);
     }
-    if (dest)
-        return dest;
-    src->charset = Parrot_ascii_charset_ptr;
-    return src;
+    return dest;
 }
 
 /*

Modified: trunk/src/string/charset/iso-8859-1.h
==============================================================================
--- trunk/src/string/charset/iso-8859-1.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/iso-8859-1.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -18,15 +18,11 @@
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-STRING * charset_cvt_iso_8859_1_to_ascii(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGMOD_NULLOK(STRING *dest))
+STRING * charset_cvt_iso_8859_1_to_ascii(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET * Parrot_charset_iso_8859_1_init(PARROT_INTERP)
+void Parrot_charset_iso_8859_1_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_charset_cvt_iso_8859_1_to_ascii \

Modified: trunk/src/string/charset/unicode.c
==============================================================================
--- trunk/src/string/charset/unicode.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/unicode.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -54,11 +54,14 @@
 static STRING* decompose(PARROT_INTERP, SHIM(STRING *src))
         __attribute__nonnull__(1);
 
-static void downcase(PARROT_INTERP, ARGIN(STRING *src))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void downcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* downcase_first(PARROT_INTERP,
+    SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
 static INTVAL find_cclass(PARROT_INTERP,
@@ -85,17 +88,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_graphemes_inplace(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *dest_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*dest_string);
-
 static INTVAL is_cclass(PARROT_INTERP,
     INTVAL flags,
     ARGIN(const STRING *source_string),
@@ -103,42 +95,36 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-static void set_graphemes(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL replace_count,
-    ARGMOD(STRING *insert_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*insert_string);
-
 PARROT_CANNOT_RETURN_NULL
 static STRING * string_from_codepoint(PARROT_INTERP, UINTVAL codepoint)
         __attribute__nonnull__(1);
 
-static void titlecase(PARROT_INTERP, ARGIN(STRING *src))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void titlecase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* titlecase_first(PARROT_INTERP,
+    SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
 PARROT_CANNOT_RETURN_NULL
-static STRING* to_charset(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+static STRING* to_charset(PARROT_INTERP, ARGIN(STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 static int u_iscclass(PARROT_INTERP, UINTVAL codepoint, INTVAL flags)
         __attribute__nonnull__(1);
 
-static void upcase(PARROT_INTERP, ARGIN(STRING *src))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void upcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING* upcase_first(PARROT_INTERP,
+    SHIM(const STRING *source_string))
         __attribute__nonnull__(1);
 
 static UINTVAL validate(PARROT_INTERP, ARGIN(STRING *src))
@@ -173,17 +159,9 @@
 #define ASSERT_ARGS_get_graphemes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_get_graphemes_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(dest_string))
 #define ASSERT_ARGS_is_cclass __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_set_graphemes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(insert_string))
 #define ASSERT_ARGS_string_from_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_titlecase __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -223,27 +201,6 @@
 
 #define UNIMPL EXCEPTION(EXCEPTION_UNIMPLEMENTED, "unimplemented unicode")
 
-/*
-
-=item C<static void set_graphemes(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL replace_count, STRING *insert_string)>
-
-Sets C<replace_count> graphemes in STRING C<source_string> starting at offset
-C<offset>.  Gets the graphemes to be replaced from STRING C<insert_string>.
-
-=cut
-
-*/
-
-static void
-set_graphemes(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL replace_count, ARGMOD(STRING *insert_string))
-{
-    ASSERT_ARGS(set_graphemes)
-    ENCODING_SET_CODEPOINTS(interp, source_string, offset,
-            replace_count, insert_string);
-}
-
 
 /*
 
@@ -269,30 +226,7 @@
 
 /*
 
-=item C<static STRING * get_graphemes_inplace(PARROT_INTERP, STRING
-*source_string, UINTVAL offset, UINTVAL count, STRING *dest_string)>
-
-Gets C<count> graphemes in place from STRING C<source_string> starting at
-offset C<offset>. Puts them into STRING C<dest_string>.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_graphemes_inplace(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *dest_string))
-{
-    ASSERT_ARGS(get_graphemes_inplace)
-    return ENCODING_GET_CODEPOINTS_INPLACE(interp, source_string,
-            offset, count, dest_string);
-}
-
-
-/*
-
-=item C<static STRING* to_charset(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING* to_charset(PARROT_INTERP, STRING *src)>
 
 Converts input STRING C<src> to unicode STRING C<dest>.
 
@@ -302,7 +236,7 @@
 
 PARROT_CANNOT_RETURN_NULL
 static STRING*
-to_charset(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
+to_charset(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(to_charset)
     const charset_converter_t conversion_func =
@@ -310,9 +244,9 @@
                     Parrot_unicode_charset_ptr);
 
     if (conversion_func)
-         return conversion_func(interp, src, dest);
+         return conversion_func(interp, src);
 
-    return Parrot_utf8_encoding_ptr->to_encoding(interp, src, dest);
+    return Parrot_utf8_encoding_ptr->to_encoding(interp, src);
 }
 
 
@@ -401,7 +335,7 @@
 
 /*
 
-=item C<static void upcase(PARROT_INTERP, STRING *src)>
+=item C<static STRING* upcase(PARROT_INTERP, const STRING *src)>
 
 Converts the STRING C<src> to all upper-case graphemes, for those characters
 which support upper-case versions.
@@ -412,23 +346,25 @@
 
 */
 
-static void
-upcase(PARROT_INTERP, ARGIN(STRING *src))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(upcase)
 #if PARROT_HAS_ICU
     UErrorCode err;
     int dest_len, src_len, needed;
+    STRING *res;
 #endif
 
     if (src->bufused  == src->strlen
             && src->encoding == Parrot_utf8_encoding_ptr) {
-        Parrot_ascii_charset_ptr->upcase(interp, src);
-        return;
+        return Parrot_ascii_charset_ptr->upcase(interp, src);
     }
 
 #if PARROT_HAS_ICU
-    src = Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
+    /* to_encoding will allocate new string */
+    res = Parrot_utf16_encoding_ptr->to_encoding(interp, src);
     /*
        U_CAPI int32_t U_EXPORT2
        u_strToUpper(UChar *dest, int32_t destCapacity,
@@ -440,8 +376,8 @@
 
     /* use all available space - see below XXX */
     /* TODO downcase, titlecase too */
-    dest_len = Buffer_buflen(src) / sizeof (UChar);
-    src_len  = src->bufused     / sizeof (UChar);
+    dest_len = Buffer_buflen(res) / sizeof (UChar);
+    src_len  = res->bufused       / sizeof (UChar);
 
     /*
      * XXX troubles:
@@ -460,33 +396,35 @@
      *  TODO downcase, titlecase
      */
     needed = u_strToUpper(NULL, 0,
-            (UChar *)src->strstart, src_len,
+            (UChar *)res->strstart, src_len,
             NULL,       /* locale = default */
             &err);
 
     if (needed > dest_len) {
-        Parrot_gc_reallocate_string_storage(interp, src, needed * sizeof (UChar));
+        Parrot_gc_reallocate_string_storage(interp, res, needed * sizeof (UChar));
         dest_len = needed;
     }
 
     err      = U_ZERO_ERROR;
-    dest_len = u_strToUpper((UChar *)src->strstart, dest_len,
-            (UChar *)src->strstart, src_len,
+    dest_len = u_strToUpper((UChar *)res->strstart, dest_len,
+            (UChar *)res->strstart, src_len,
             NULL,       /* locale = default */
             &err);
     PARROT_ASSERT(U_SUCCESS(err));
-    src->bufused = dest_len * sizeof (UChar);
+    res->bufused = dest_len * sizeof (UChar);
 
     /* downgrade if possible */
     if (dest_len == (int)src->strlen)
-        src->encoding = Parrot_ucs2_encoding_ptr;
+        res->encoding = Parrot_ucs2_encoding_ptr;
     else {
         /* string is likely still ucs2 if it was earlier
          * but strlen changed due to combining char
          */
-        src->strlen = dest_len;
+        res->strlen = dest_len;
     }
 
+    return res;
+
 #else
     UNUSED(src);
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
@@ -497,7 +435,7 @@
 
 /*
 
-=item C<static void downcase(PARROT_INTERP, STRING *src)>
+=item C<static STRING* downcase(PARROT_INTERP, const STRING *src)>
 
 Converts all graphemes to lower-case, for those graphemes which have cases.
 
@@ -507,23 +445,25 @@
 
 */
 
-static void
-downcase(PARROT_INTERP, ARGIN(STRING *src))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(downcase)
 #if PARROT_HAS_ICU
     UErrorCode err;
     int dest_len, src_len;
+    STRING *res;
 #endif
 
     if (src->bufused  == src->strlen
             && src->encoding == Parrot_utf8_encoding_ptr) {
-        Parrot_ascii_charset_ptr->downcase(interp, src);
-        return;
+        return Parrot_ascii_charset_ptr->downcase(interp, src);
     }
 
 #if PARROT_HAS_ICU
-    src = Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
+    /* to_encoding will allocate new string */
+    res = Parrot_utf16_encoding_ptr->to_encoding(interp, src);
     /*
 U_CAPI int32_t U_EXPORT2
 u_strToLower(UChar *dest, int32_t destCapacity,
@@ -532,26 +472,29 @@
              UErrorCode *pErrorCode);
      */
     err      = U_ZERO_ERROR;
-    src_len  = src->bufused / sizeof (UChar);
-    dest_len = u_strToLower((UChar *)src->strstart, src_len,
-            (UChar *)src->strstart, src_len,
+    src_len  = res->bufused / sizeof (UChar);
+    dest_len = u_strToLower((UChar *)res->strstart, src_len,
+            (UChar *)res->strstart, src_len,
             NULL,       /* locale = default */
             &err);
-    src->bufused = dest_len * sizeof (UChar);
+    res->bufused = dest_len * sizeof (UChar);
 
     if (!U_SUCCESS(err)) {
         err = U_ZERO_ERROR;
-        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
-        dest_len = u_strToLower((UChar *)src->strstart, dest_len,
-                (UChar *)src->strstart, src_len,
+        Parrot_gc_reallocate_string_storage(interp, res, res->bufused);
+        dest_len = u_strToLower((UChar *)res->strstart, dest_len,
+                (UChar *)res->strstart, src_len,
                 NULL,       /* locale = default */
                 &err);
         PARROT_ASSERT(U_SUCCESS(err));
     }
 
     /* downgrade if possible */
-    if (dest_len == (int)src->strlen)
-        src->encoding = Parrot_ucs2_encoding_ptr;
+    if (dest_len == (int)res->strlen)
+        res->encoding = Parrot_ucs2_encoding_ptr;
+
+    return res;
+
 #else
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
         "no ICU lib loaded");
@@ -561,7 +504,7 @@
 
 /*
 
-=item C<static void titlecase(PARROT_INTERP, STRING *src)>
+=item C<static STRING* titlecase(PARROT_INTERP, const STRING *src)>
 
 Converts the string to title case, for those characters which support cases.
 
@@ -571,22 +514,24 @@
 
 */
 
-static void
-titlecase(PARROT_INTERP, ARGIN(STRING *src))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(titlecase)
 #if PARROT_HAS_ICU
 
     UErrorCode err;
     int dest_len, src_len;
+    STRING *res;
 
     if (src->bufused  == src->strlen
     &&  src->encoding == Parrot_utf8_encoding_ptr) {
-        Parrot_ascii_charset_ptr->titlecase(interp, src);
-        return;
+        return Parrot_ascii_charset_ptr->titlecase(interp, src);
     }
 
-    src = Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
+    /* to_encoding will allocate new string */
+    res = Parrot_utf16_encoding_ptr->to_encoding(interp, src);
 
     /*
 U_CAPI int32_t U_EXPORT2
@@ -598,27 +543,30 @@
      */
 
     err      = U_ZERO_ERROR;
-    src_len  = src->bufused / sizeof (UChar);
-    dest_len = u_strToTitle((UChar *)src->strstart, src_len,
-            (UChar *)src->strstart, src_len,
+    src_len  = res->bufused / sizeof (UChar);
+    dest_len = u_strToTitle((UChar *)res->strstart, src_len,
+            (UChar *)res->strstart, src_len,
             NULL,       /* default titleiter */
             NULL,       /* locale = default */
             &err);
-    src->bufused = dest_len * sizeof (UChar);
+    res->bufused = dest_len * sizeof (UChar);
 
     if (!U_SUCCESS(err)) {
         err = U_ZERO_ERROR;
-        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
-        dest_len = u_strToTitle((UChar *)src->strstart, dest_len,
-                (UChar *)src->strstart, src_len,
+        Parrot_gc_reallocate_string_storage(interp, res, res->bufused);
+        dest_len = u_strToTitle((UChar *)res->strstart, dest_len,
+                (UChar *)res->strstart, src_len,
                 NULL, NULL,
                 &err);
         PARROT_ASSERT(U_SUCCESS(err));
     }
 
     /* downgrade if possible */
-    if (dest_len == (int)src->strlen)
-        src->encoding = Parrot_ucs2_encoding_ptr;
+    if (dest_len == (int)res->strlen)
+        res->encoding = Parrot_ucs2_encoding_ptr;
+
+    return res;
+
 #else
     UNUSED(src);
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
@@ -629,7 +577,7 @@
 
 /*
 
-=item C<static void upcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* upcase_first(PARROT_INTERP, const STRING *source_string)>
 
 Converts the first grapheme in the STRING C<source_string> to uppercase, if the
 grapheme supports it. Not implemented.
@@ -638,8 +586,9 @@
 
 */
 
-static void
-upcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+upcase_first(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(upcase_first)
     /* TODO: https://trac.parrot.org/parrot/wiki/StringsTasklist Implement this. */
@@ -649,7 +598,8 @@
 
 /*
 
-=item C<static void downcase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* downcase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Converts the first grapheme in the STRING C<source_string> to lower-case, if
 the grapheme supports it. Not implemented
@@ -658,8 +608,9 @@
 
 */
 
-static void
-downcase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+downcase_first(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(downcase_first)
     /* TODO: https://trac.parrot.org/parrot/wiki/StringsTasklist Implement this. */
@@ -669,7 +620,8 @@
 
 /*
 
-=item C<static void titlecase_first(PARROT_INTERP, STRING *source_string)>
+=item C<static STRING* titlecase_first(PARROT_INTERP, const STRING
+*source_string)>
 
 Converts the first grapheme in STRING C<source_string> to title case, if the
 string supports it. Not implemented.
@@ -678,8 +630,9 @@
 
 */
 
-static void
-titlecase_first(PARROT_INTERP, SHIM(STRING *source_string))
+PARROT_CANNOT_RETURN_NULL
+static STRING*
+titlecase_first(PARROT_INTERP, SHIM(const STRING *source_string))
 {
     ASSERT_ARGS(titlecase_first)
     /* TODO: https://trac.parrot.org/parrot/wiki/StringsTasklist Implement this. */
@@ -1064,7 +1017,7 @@
 
 /*
 
-=item C<const CHARSET * Parrot_charset_unicode_init(PARROT_INTERP)>
+=item C<void Parrot_charset_unicode_init(PARROT_INTERP)>
 
 Initializes the Unicode charset by installing all the necessary function
 pointers.
@@ -1073,8 +1026,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET *
+void
 Parrot_charset_unicode_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_charset_unicode_init)
@@ -1082,8 +1034,6 @@
     static const CHARSET base_set   = {
         "unicode",
         get_graphemes,
-        get_graphemes_inplace,
-        set_graphemes,
         to_charset,
         compose,
         decompose,
@@ -1115,7 +1065,8 @@
      */
     return_set->preferred_encoding = Parrot_utf8_encoding_ptr;
     Parrot_register_charset(interp, "unicode", return_set);
-    return return_set;
+
+    return;
 }
 
 

Modified: trunk/src/string/charset/unicode.h
==============================================================================
--- trunk/src/string/charset/unicode.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/charset/unicode.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -21,8 +21,7 @@
 /* HEADERIZER BEGIN: src/string/charset/unicode.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-const CHARSET * Parrot_charset_unicode_init(PARROT_INTERP)
+void Parrot_charset_unicode_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_Parrot_charset_unicode_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/string/encoding/fixed_8.c
==============================================================================
--- trunk/src/string/encoding/fixed_8.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/fixed_8.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -24,13 +24,10 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void become_encoding(PARROT_INTERP, SHIM(STRING *source_string))
-        __attribute__nonnull__(1);
-
-static UINTVAL bytes(SHIM_INTERP, ARGIN(STRING *source_string))
+static UINTVAL bytes(SHIM_INTERP, ARGIN(const STRING *source_string))
         __attribute__nonnull__(2);
 
-static UINTVAL codepoints(PARROT_INTERP, ARGIN(STRING *source_string))
+static UINTVAL codepoints(PARROT_INTERP, ARGIN(const STRING *source_string))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -83,18 +80,6 @@
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_bytes_inplace(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *return_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*return_string);
-
-PARROT_WARN_UNUSED_RESULT
 static UINTVAL get_codepoint(PARROT_INTERP,
     ARGIN(const STRING *source_string),
     UINTVAL offset)
@@ -110,18 +95,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_codepoints_inplace(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *dest_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*dest_string);
-
 static void iter_init(SHIM_INTERP,
     ARGIN(const STRING *src),
     ARGOUT(String_iter *iter))
@@ -136,42 +109,11 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void set_bytes(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *new_bytes))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*new_bytes);
-
-static void set_codepoint(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL codepoint)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void set_codepoints(PARROT_INTERP,
-    ARGIN(STRING *source_string),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *new_codepoints))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*new_codepoints);
-
 PARROT_DOES_NOT_RETURN
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_encoding(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(STRING *dest))
+static STRING * to_encoding(PARROT_INTERP, SHIM(const STRING *src))
         __attribute__nonnull__(1);
 
-#define ASSERT_ARGS_become_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -195,37 +137,18 @@
 #define ASSERT_ARGS_get_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_get_bytes_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(return_string))
 #define ASSERT_ARGS_get_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
 #define ASSERT_ARGS_get_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_get_codepoints_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(dest_string))
 #define ASSERT_ARGS_iter_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(src) \
     , PARROT_ASSERT_ARG(iter))
 #define ASSERT_ARGS_set_byte __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_set_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(new_bytes))
-#define ASSERT_ARGS_set_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string))
-#define ASSERT_ARGS_set_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(source_string) \
-    , PARROT_ASSERT_ARG(new_codepoints))
 #define ASSERT_ARGS_to_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
@@ -236,7 +159,7 @@
 
 /*
 
-=item C<static STRING * to_encoding(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_encoding(PARROT_INTERP, const STRING *src)>
 
 Converts the string C<src> to this particular encoding.  If C<dest> is
 provided, it will contain the result.  Otherwise this function operates in
@@ -250,7 +173,7 @@
 PARROT_DOES_NOT_RETURN
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_encoding(PARROT_INTERP, SHIM(STRING *src), SHIM(STRING *dest))
+to_encoding(PARROT_INTERP, SHIM(const STRING *src))
 {
     ASSERT_ARGS(to_encoding)
     UNIMPL;
@@ -277,25 +200,6 @@
     return get_byte(interp, source_string, offset);
 }
 
-/*
-
-=item C<static void set_codepoint(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL codepoint)>
-
-This is the same as set byte
-
-=cut
-
-*/
-
-static void
-set_codepoint(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL codepoint)
-{
-    ASSERT_ARGS(set_codepoint)
-    set_byte(interp, source_string, offset, codepoint);
-}
-
 
 /*
 
@@ -419,8 +323,8 @@
 get_bytes(PARROT_INTERP, ARGIN(STRING *source_string), UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(get_bytes)
-    STRING * const return_string = Parrot_str_new_COW(interp,
-            source_string);
+    STRING * const return_string = Parrot_str_copy(interp, source_string);
+
     return_string->encoding = source_string->encoding;
     return_string->charset = source_string->charset;
 
@@ -436,117 +340,7 @@
 
 /*
 
-=item C<static STRING * get_codepoints_inplace(PARROT_INTERP, STRING
-*source_string, UINTVAL offset, UINTVAL count, STRING *dest_string)>
-
-Gets from string C<src> at position C<offset> C<count> codepoints and returns
-them in C<return_string>.  (Delegates to C<get_bytes>.)
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_codepoints_inplace(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *dest_string))
-{
-    ASSERT_ARGS(get_codepoints_inplace)
-    return get_bytes_inplace(interp, source_string, offset,
-            count, dest_string);
-}
-
-/*
-
-=item C<static STRING * get_bytes_inplace(PARROT_INTERP, STRING *source_string,
-UINTVAL offset, UINTVAL count, STRING *return_string)>
-
-Gets from string C<src> at position C<offset> C<count> bytes and returns them
-in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_bytes_inplace(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *return_string))
-{
-    ASSERT_ARGS(get_bytes_inplace)
-    Parrot_str_reuse_COW(interp, source_string, return_string);
-
-    return_string->strstart = (char *)return_string->strstart + offset ;
-    return_string->bufused = count;
-
-    return_string->strlen = count;
-    return_string->hashval = 0;
-
-    return return_string;
-}
-
-/*
-
-=item C<static void set_codepoints(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL count, STRING *new_codepoints)>
-
-Delegate to set_bytes
-
-=cut
-
-*/
-
-static void
-set_codepoints(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *new_codepoints))
-{
-    ASSERT_ARGS(set_codepoints)
-    set_bytes(interp, source_string, offset, count, new_codepoints);
-}
-
-/*
-
-=item C<static void set_bytes(PARROT_INTERP, STRING *source_string, UINTVAL
-offset, UINTVAL count, STRING *new_bytes)>
-
-Replaces in string C<src> at position C<offset> for C<count> bytes with the
-contents of string C<new_bytes>.
-
-=cut
-
-*/
-
-static void
-set_bytes(PARROT_INTERP, ARGIN(STRING *source_string),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *new_bytes))
-{
-    ASSERT_ARGS(set_bytes)
-    Parrot_str_replace(interp, source_string, offset, count, new_bytes, NULL);
-}
-
-/*
-
-=item C<static void become_encoding(PARROT_INTERP, STRING *source_string)>
-
-Unconditionally makes the string be in this encoding, if that's valid
-
-=cut
-
-*/
-
-static void
-become_encoding(PARROT_INTERP, SHIM(STRING *source_string))
-{
-    ASSERT_ARGS(become_encoding)
-    UNIMPL;
-}
-
-
-/*
-
-=item C<static UINTVAL codepoints(PARROT_INTERP, STRING *source_string)>
+=item C<static UINTVAL codepoints(PARROT_INTERP, const STRING *source_string)>
 
 Returns the number of codepoints in string C<src>.
 
@@ -555,7 +349,7 @@
 */
 
 static UINTVAL
-codepoints(PARROT_INTERP, ARGIN(STRING *source_string))
+codepoints(PARROT_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(codepoints)
     return bytes(interp, source_string);
@@ -563,7 +357,7 @@
 
 /*
 
-=item C<static UINTVAL bytes(PARROT_INTERP, STRING *source_string)>
+=item C<static UINTVAL bytes(PARROT_INTERP, const STRING *source_string)>
 
 Returns the number of bytes in string C<src>.
 
@@ -572,7 +366,7 @@
 */
 
 static UINTVAL
-bytes(SHIM_INTERP, ARGIN(STRING *source_string))
+bytes(SHIM_INTERP, ARGIN(const STRING *source_string))
 {
     ASSERT_ARGS(bytes)
     return source_string->bufused;
@@ -693,7 +487,7 @@
 
 /*
 
-=item C<ENCODING * Parrot_encoding_fixed_8_init(PARROT_INTERP)>
+=item C<void Parrot_encoding_fixed_8_init(PARROT_INTERP)>
 
 Initializes the fixed-8 encoding.
 
@@ -701,8 +495,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING *
+void
 Parrot_encoding_fixed_8_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_encoding_fixed_8_init)
@@ -713,26 +506,21 @@
         1, /* Max bytes per codepoint */
         to_encoding,
         get_codepoint,
-        set_codepoint,
         get_byte,
         set_byte,
         get_codepoints,
-        get_codepoints_inplace,
         get_bytes,
-        get_bytes_inplace,
-        set_codepoints,
-        set_bytes,
-        become_encoding,
         codepoints,
         bytes,
         iter_init,
         find_cclass,
         fixed_8_hash
-
     };
+
     STRUCT_COPY_FROM_STRUCT(return_encoding, base_encoding);
     Parrot_register_encoding(interp, "fixed_8", return_encoding);
-    return return_encoding;
+
+    return;
 }
 
 

Modified: trunk/src/string/encoding/fixed_8.h
==============================================================================
--- trunk/src/string/encoding/fixed_8.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/fixed_8.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -16,8 +16,7 @@
 /* HEADERIZER BEGIN: src/string/encoding/fixed_8.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING * Parrot_encoding_fixed_8_init(PARROT_INTERP)
+void Parrot_encoding_fixed_8_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_Parrot_encoding_fixed_8_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/string/encoding/ucs2.c
==============================================================================
--- trunk/src/string/encoding/ucs2.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/ucs2.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -36,15 +36,12 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void become_encoding(PARROT_INTERP, SHIM(STRING *src))
-        __attribute__nonnull__(1);
-
 PARROT_WARN_UNUSED_RESULT
-static UINTVAL bytes(SHIM_INTERP, ARGIN(STRING *src))
+static UINTVAL bytes(SHIM_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-static UINTVAL codepoints(PARROT_INTERP, ARGIN(STRING *src))
+static UINTVAL codepoints(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -72,15 +69,6 @@
     SHIM(UINTVAL count))
         __attribute__nonnull__(1);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_bytes_inplace(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *return_string))
-        __attribute__nonnull__(1);
-
 static UINTVAL get_codepoint(PARROT_INTERP,
     ARGIN(const STRING *src),
     UINTVAL offset)
@@ -96,15 +84,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_codepoints_inplace(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *dest_string))
-        __attribute__nonnull__(1);
-
 static void iter_init(PARROT_INTERP,
     ARGIN(const STRING *src),
     ARGOUT(String_iter *iter))
@@ -119,36 +98,11 @@
     SHIM(UINTVAL byte))
         __attribute__nonnull__(1);
 
-static void set_bytes(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *new_bytes))
-        __attribute__nonnull__(1);
-
-static void set_codepoint(PARROT_INTERP,
-    ARGIN(STRING *src),
-    UINTVAL offset,
-    UINTVAL codepoint)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void set_codepoints(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *new_codepoints))
-        __attribute__nonnull__(1);
-
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_encoding(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGMOD(STRING *dest))
+static STRING * to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
 static UINTVAL ucs2_decode_and_advance(SHIM_INTERP, ARGMOD(String_iter *i))
         __attribute__nonnull__(2)
@@ -172,8 +126,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*i);
 
-#define ASSERT_ARGS_become_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -187,33 +139,21 @@
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_get_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_get_bytes_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_get_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_get_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_get_codepoints_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_iter_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src) \
     , PARROT_ASSERT_ARG(iter))
 #define ASSERT_ARGS_set_byte __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_set_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_set_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_set_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_to_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src) \
-    , PARROT_ASSERT_ARG(dest))
+    , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_ucs2_decode_and_advance __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(i))
 #define ASSERT_ARGS_ucs2_encode_and_advance __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -237,7 +177,7 @@
 
 /*
 
-=item C<static STRING * to_encoding(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_encoding(PARROT_INTERP, const STRING *src)>
 
 Converts the string C<src> to this particular encoding.  If C<dest> is
 provided, it will contain the result.  Otherwise this function operates in
@@ -250,11 +190,11 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_encoding(PARROT_INTERP, ARGIN(STRING *src), ARGMOD(STRING *dest))
+to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(to_encoding)
     STRING * const result =
-        Parrot_utf16_encoding_ptr->to_encoding(interp, src, dest);
+        Parrot_utf16_encoding_ptr->to_encoding(interp, src);
 
     /* conversion to utf16 downgrads to ucs-2 if possible - check result */
     if (result->encoding == Parrot_utf16_encoding_ptr)
@@ -283,37 +223,12 @@
     const UChar * const s = (const UChar*) src->strstart;
     return s[offset];
 #else
+    UNUSED(offset);
     UNUSED(src);
-    UNUSED(offset)
     no_ICU_lib(interp);
 #endif
 }
 
-/*
-
-=item C<static void set_codepoint(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL codepoint)>
-
-Sets, in string C<src> at position C<offset>, the codepoint C<codepoint>.
-
-=cut
-
-*/
-
-static void
-set_codepoint(PARROT_INTERP, ARGIN(STRING *src), UINTVAL offset, UINTVAL codepoint)
-{
-    ASSERT_ARGS(set_codepoint)
-#if PARROT_HAS_ICU
-    UChar * const s = (UChar*) src->strstart;
-    s[offset] = codepoint;
-#else
-    UNUSED(src)
-    UNUSED(offset)
-    UNUSED(codepoint)
-    no_ICU_lib(interp);
-#endif
-}
 
 /*
 
@@ -397,7 +312,8 @@
 get_codepoints(PARROT_INTERP, ARGIN(STRING *src), UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(get_codepoints)
-    STRING * const return_string = Parrot_str_new_COW(interp, src);
+    STRING * const return_string = Parrot_str_copy(interp, src);
+
 #if PARROT_HAS_ICU
     return_string->strstart = (char*)src->strstart + offset * sizeof (UChar);
     return_string->bufused = count * sizeof (UChar);
@@ -443,109 +359,7 @@
 
 /*
 
-=item C<static STRING * get_codepoints_inplace(PARROT_INTERP, STRING *src,
-UINTVAL offset, UINTVAL count, STRING *dest_string)>
-
-Gets from string C<src> at position C<offset> C<count> codepoints and returns
-them in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_codepoints_inplace(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *dest_string))
-{
-    ASSERT_ARGS(get_codepoints_inplace)
-    UNIMPL;
-}
-
-/*
-
-=item C<static STRING * get_bytes_inplace(PARROT_INTERP, STRING *src, UINTVAL
-offset, UINTVAL count, STRING *return_string)>
-
-Gets from string C<src> at position C<offset> C<count> bytes and returns them
-in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_bytes_inplace(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *return_string))
-{
-    ASSERT_ARGS(get_bytes_inplace)
-    UNIMPL;
-}
-
-/*
-
-=item C<static void set_codepoints(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL count, STRING *new_codepoints)>
-
-Replaces in string C<src> at position C<offset> for C<count> codepoints with
-the contents of string C<new_codepoints>.
-
-=cut
-
-*/
-
-static void
-set_codepoints(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_codepoints))
-{
-    ASSERT_ARGS(set_codepoints)
-    UNIMPL;
-}
-
-/*
-
-=item C<static void set_bytes(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL count, STRING *new_bytes)>
-
-Replaces in string C<src> at position C<offset> for C<count> bytes with the
-contents of string C<new_bytes>.
-
-=cut
-
-*/
-
-static void
-set_bytes(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_bytes))
-{
-    ASSERT_ARGS(set_bytes)
-    UNIMPL;
-}
-
-/*
-
-=item C<static void become_encoding(PARROT_INTERP, STRING *src)>
-
-Unconditionally makes the string be in this encoding, if that's valid
-
-=cut
-
-*/
-
-static void
-become_encoding(PARROT_INTERP, SHIM(STRING *src))
-{
-    ASSERT_ARGS(become_encoding)
-    UNIMPL;
-}
-
-
-/*
-
-=item C<static UINTVAL codepoints(PARROT_INTERP, STRING *src)>
+=item C<static UINTVAL codepoints(PARROT_INTERP, const STRING *src)>
 
 Returns the number of codepoints in string C<src>.
 
@@ -555,10 +369,11 @@
 
 PARROT_WARN_UNUSED_RESULT
 static UINTVAL
-codepoints(PARROT_INTERP, ARGIN(STRING *src))
+codepoints(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(codepoints)
 #if PARROT_HAS_ICU
+    UNUSED(interp);
     return src->bufused / sizeof (UChar);
 #else
     UNUSED(src);
@@ -568,7 +383,7 @@
 
 /*
 
-=item C<static UINTVAL bytes(PARROT_INTERP, STRING *src)>
+=item C<static UINTVAL bytes(PARROT_INTERP, const STRING *src)>
 
 Returns the number of bytes in string C<src>.
 
@@ -578,7 +393,7 @@
 
 PARROT_WARN_UNUSED_RESULT
 static UINTVAL
-bytes(SHIM_INTERP, ARGIN(STRING *src))
+bytes(SHIM_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(bytes)
     return src->bufused;
@@ -638,9 +453,9 @@
     ASSERT_ARGS(ucs2_encode_and_advance)
 
 #if PARROT_HAS_ICU
-    UChar * const s = (UChar*) i->str->strstart;
+    UChar    *s = (UChar*) i->str->strstart;
     UINTVAL pos = i->bytepos / sizeof (UChar);
-    s[pos++] = (UChar)c;
+    s[pos++]    = (UChar)c;
     i->charpos++;
     i->bytepos = pos * sizeof (UChar);
 #else
@@ -748,7 +563,7 @@
 
 /*
 
-=item C<ENCODING * Parrot_encoding_ucs2_init(PARROT_INTERP)>
+=item C<void Parrot_encoding_ucs2_init(PARROT_INTERP)>
 
 Initializes the UCS-2 encoding.
 
@@ -756,8 +571,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING *
+void
 Parrot_encoding_ucs2_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_encoding_ucs2_init)
@@ -768,16 +582,10 @@
         2, /* Max bytes per codepoint 0 .. 0x10ffff */
         to_encoding,
         get_codepoint,
-        set_codepoint,
         get_byte,
         set_byte,
         get_codepoints,
-        get_codepoints_inplace,
         get_bytes,
-        get_bytes_inplace,
-        set_codepoints,
-        set_bytes,
-        become_encoding,
         codepoints,
         bytes,
         iter_init,
@@ -786,7 +594,8 @@
     };
     STRUCT_COPY_FROM_STRUCT(return_encoding, base_encoding);
     Parrot_register_encoding(interp, "ucs2", return_encoding);
-    return return_encoding;
+
+    return;
 }
 
 /*

Modified: trunk/src/string/encoding/ucs2.h
==============================================================================
--- trunk/src/string/encoding/ucs2.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/ucs2.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -16,8 +16,7 @@
 /* HEADERIZER BEGIN: src/string/encoding/ucs2.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING * Parrot_encoding_ucs2_init(PARROT_INTERP)
+void Parrot_encoding_ucs2_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_Parrot_encoding_ucs2_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/string/encoding/utf16.c
==============================================================================
--- trunk/src/string/encoding/utf16.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/utf16.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -26,15 +26,12 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void become_encoding(PARROT_INTERP, SHIM(STRING *src))
-        __attribute__nonnull__(1);
-
 PARROT_WARN_UNUSED_RESULT
-static UINTVAL bytes(SHIM_INTERP, ARGIN(STRING *src))
+static UINTVAL bytes(SHIM_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-static UINTVAL codepoints(PARROT_INTERP, ARGIN(STRING *src))
+static UINTVAL codepoints(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -63,17 +60,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_bytes_inplace(PARROT_INTERP,
-    ARGIN(STRING *src),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGIN(STRING *return_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5);
-
 static UINTVAL get_codepoint(PARROT_INTERP,
     ARGIN(const STRING *src),
     UINTVAL offset)
@@ -89,18 +75,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_codepoints_inplace(PARROT_INTERP,
-    ARGIN(STRING *src),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *return_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*return_string);
-
 static void iter_init(PARROT_INTERP,
     ARGIN(const STRING *src),
     ARGOUT(String_iter *iter))
@@ -116,34 +90,9 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void set_bytes(PARROT_INTERP,
-    SHIM(STRING *src),
-    UINTVAL offset,
-    UINTVAL count,
-    SHIM(STRING *new_bytes))
-        __attribute__nonnull__(1);
-
-static void set_codepoint(PARROT_INTERP,
-    ARGIN(STRING *src),
-    UINTVAL offset,
-    UINTVAL codepoint)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void set_codepoints(PARROT_INTERP,
-    ARGIN(STRING *src),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGIN(STRING *new_codepoints))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5);
-
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static STRING * to_encoding(PARROT_INTERP,
-    ARGIN(STRING *src),
-    ARGIN_NULLOK(STRING *dest))
+static STRING * to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -168,8 +117,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*i);
 
-#define ASSERT_ARGS_become_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -184,20 +131,12 @@
 #define ASSERT_ARGS_get_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_get_bytes_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src) \
-    , PARROT_ASSERT_ARG(return_string))
 #define ASSERT_ARGS_get_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_get_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_get_codepoints_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src) \
-    , PARROT_ASSERT_ARG(return_string))
 #define ASSERT_ARGS_iter_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src) \
@@ -205,15 +144,6 @@
 #define ASSERT_ARGS_set_byte __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_set_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_set_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_set_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src) \
-    , PARROT_ASSERT_ARG(new_codepoints))
 #define ASSERT_ARGS_to_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
@@ -242,7 +172,7 @@
 
 /*
 
-=item C<static STRING * to_encoding(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_encoding(PARROT_INTERP, const STRING *src)>
 
 Converts the string C<src> to this particular encoding.  If C<dest> is
 provided, it will contain the result.  Otherwise this function operates in
@@ -256,7 +186,7 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-to_encoding(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest))
+to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(to_encoding)
 #if PARROT_HAS_ICU
@@ -265,22 +195,18 @@
     UChar *p;
 #endif
     int src_len;
-    int in_place = dest == NULL;
     STRING *result;
 
     if (src->encoding == Parrot_utf16_encoding_ptr ||
             src->encoding == Parrot_ucs2_encoding_ptr)
-        return in_place ? src : Parrot_str_copy(interp, src);
+        return Parrot_str_clone(interp, src);
+
+    result = Parrot_gc_new_string_header(interp, 0);
+
     /*
      * TODO adapt string creation functions
      */
     src_len = src->strlen;
-    if (in_place) {
-        result = src;
-    }
-    else {
-        result = dest;
-    }
     if (!src_len) {
         result->charset  = Parrot_unicode_charset_ptr;
         result->encoding = Parrot_ucs2_encoding_ptr;
@@ -296,14 +222,9 @@
        UErrorCode *pErrorCode);
        */
 #if PARROT_HAS_ICU
-    if (in_place) {
-        /* need intermediate memory */
-        p = mem_gc_allocate_n_typed(interp, src_len, UChar);
-    }
-    else {
-        Parrot_gc_reallocate_string_storage(interp, dest, sizeof (UChar) * src_len);
-        p = (UChar *)dest->strstart;
-    }
+    Parrot_gc_allocate_string_storage(interp, result, sizeof (UChar) * src_len);
+    p = (UChar *)result->strstart;
+
     if (src->charset == Parrot_iso_8859_1_charset_ptr ||
             src->charset == Parrot_ascii_charset_ptr) {
         for (dest_len = 0; dest_len < (int)src->strlen; ++dest_len) {
@@ -318,25 +239,16 @@
             /*
              * have to resize - required len in UChars is in dest_len
              */
-            if (in_place)
-                p = mem_gc_realloc_n_typed(interp, p, dest_len, UChar);
-            else {
-                result->bufused = dest_len * sizeof (UChar);
-                Parrot_gc_reallocate_string_storage(interp, dest,
-                                         sizeof (UChar) * dest_len);
-                p = (UChar *)dest->strstart;
-            }
+            result->bufused = dest_len * sizeof (UChar);
+            Parrot_gc_reallocate_string_storage(interp, result,
+                                     sizeof (UChar) * dest_len);
+            p = (UChar *)result->strstart;
             u_strFromUTF8(p, dest_len,
                     &dest_len, src->strstart, src->bufused, &err);
             PARROT_ASSERT(U_SUCCESS(err));
         }
     }
     result->bufused = dest_len * sizeof (UChar);
-    if (in_place) {
-        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
-        memcpy(src->strstart, p, src->bufused);
-        mem_gc_free(interp, p);
-    }
     result->charset  = Parrot_unicode_charset_ptr;
     result->encoding = Parrot_utf16_encoding_ptr;
     result->strlen = src_len;
@@ -383,27 +295,6 @@
 #endif
 }
 
-/*
-
-=item C<static void set_codepoint(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL codepoint)>
-
-Sets, in string C<src> at position C<offset>, the codepoint C<codepoint>.
-
-=cut
-
-*/
-
-static void
-set_codepoint(PARROT_INTERP, ARGIN(STRING *src), UINTVAL offset, UINTVAL codepoint)
-{
-    ASSERT_ARGS(set_codepoint)
-    UNUSED(interp);
-    UNUSED(src);
-    UNUSED(offset);
-    UNUSED(codepoint);
-    UNIMPL;
-}
 
 /*
 
@@ -502,7 +393,7 @@
     ASSERT_ARGS(get_codepoints)
     String_iter iter;
     UINTVAL start;
-    STRING * const return_string = Parrot_str_new_COW(interp, src);
+    STRING * const return_string = Parrot_str_copy(interp, src);
 
     iter_init(interp, src, &iter);
     iter.set_position(interp, &iter, offset);
@@ -518,39 +409,6 @@
 
 /*
 
-=item C<static STRING * get_codepoints_inplace(PARROT_INTERP, STRING *src,
-UINTVAL offset, UINTVAL count, STRING *return_string)>
-
-Gets from string C<src> at position C<offset> C<count> codepoints and returns
-them in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_codepoints_inplace(PARROT_INTERP, ARGIN(STRING *src),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *return_string))
-{
-    ASSERT_ARGS(get_codepoints_inplace)
-    String_iter iter;
-    UINTVAL start;
-    Parrot_str_reuse_COW(interp, src, return_string);
-    iter_init(interp, src, &iter);
-    iter.set_position(interp, &iter, offset);
-    start = iter.bytepos;
-    return_string->strstart = (char *)return_string->strstart + start ;
-    iter.set_position(interp, &iter, offset + count);
-    return_string->bufused = iter.bytepos - start;
-    return_string->strlen = count;
-    return_string->hashval = 0;
-    return return_string;
-}
-
-/*
-
 =item C<static STRING * get_bytes(PARROT_INTERP, STRING *src, UINTVAL offset,
 UINTVAL count)>
 
@@ -575,100 +433,7 @@
 
 /*
 
-=item C<static STRING * get_bytes_inplace(PARROT_INTERP, STRING *src, UINTVAL
-offset, UINTVAL count, STRING *return_string)>
-
-Gets from string C<src> at position C<offset> C<count> bytes and returns them
-in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_bytes_inplace(PARROT_INTERP, ARGIN(STRING *src),
-        UINTVAL offset, UINTVAL count, ARGIN(STRING *return_string))
-{
-    ASSERT_ARGS(get_bytes_inplace)
-    UNUSED(interp);
-    UNUSED(src);
-    UNUSED(offset)
-    UNUSED(count);
-    UNUSED(return_string);
-    UNIMPL;
-}
-
-/*
-
-=item C<static void set_codepoints(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL count, STRING *new_codepoints)>
-
-Replaces in string C<src> at position C<offset> for C<count> codepoints with
-the contents of string C<new_codepoints>.
-
-=cut
-
-*/
-
-static void
-set_codepoints(PARROT_INTERP, ARGIN(STRING *src),
-        UINTVAL offset, UINTVAL count, ARGIN(STRING *new_codepoints))
-{
-    ASSERT_ARGS(set_codepoints)
-    UNUSED(interp);
-    UNUSED(src);
-    UNUSED(offset)
-    UNUSED(count);
-    UNUSED(new_codepoints);
-    UNIMPL;
-}
-
-/*
-
-=item C<static void set_bytes(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL count, STRING *new_bytes)>
-
-Replaces in string C<src> at position C<offset> for C<count> bytes with the
-contents of string C<new_bytes>.
-
-=cut
-
-*/
-
-static void
-set_bytes(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *new_bytes))
-{
-    ASSERT_ARGS(set_bytes)
-    UNUSED(interp);
-    UNUSED(offset)
-    UNUSED(count);
-    UNIMPL;
-}
-
-/*
-
-=item C<static void become_encoding(PARROT_INTERP, STRING *src)>
-
-Unconditionally makes the string be in this encoding, if that's valid
-
-=cut
-
-*/
-
-static void
-become_encoding(PARROT_INTERP, SHIM(STRING *src))
-{
-    ASSERT_ARGS(become_encoding)
-    UNIMPL;
-}
-
-
-/*
-
-=item C<static UINTVAL codepoints(PARROT_INTERP, STRING *src)>
+=item C<static UINTVAL codepoints(PARROT_INTERP, const STRING *src)>
 
 Returns the number of codepoints in string C<src>.
 
@@ -678,7 +443,7 @@
 
 PARROT_WARN_UNUSED_RESULT
 static UINTVAL
-codepoints(PARROT_INTERP, ARGIN(STRING *src))
+codepoints(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(codepoints)
     String_iter iter;
@@ -694,7 +459,7 @@
 
 /*
 
-=item C<static UINTVAL bytes(PARROT_INTERP, STRING *src)>
+=item C<static UINTVAL bytes(PARROT_INTERP, const STRING *src)>
 
 Returns the number of bytes in string C<src>.
 
@@ -704,7 +469,7 @@
 
 PARROT_WARN_UNUSED_RESULT
 static UINTVAL
-bytes(SHIM_INTERP, ARGIN(STRING *src))
+bytes(SHIM_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(bytes)
     return src->bufused;
@@ -816,7 +581,7 @@
 
 /*
 
-=item C<ENCODING * Parrot_encoding_utf16_init(PARROT_INTERP)>
+=item C<void Parrot_encoding_utf16_init(PARROT_INTERP)>
 
 Initializes the UTF-16 encoding.
 
@@ -824,8 +589,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING *
+void
 Parrot_encoding_utf16_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_encoding_utf16_init)
@@ -836,16 +600,10 @@
         4, /* Max bytes per codepoint 0 .. 0x10ffff */
         to_encoding,
         get_codepoint,
-        set_codepoint,
         get_byte,
         set_byte,
         get_codepoints,
-        get_codepoints_inplace,
         get_bytes,
-        get_bytes_inplace,
-        set_codepoints,
-        set_bytes,
-        become_encoding,
         codepoints,
         bytes,
         iter_init,
@@ -854,7 +612,8 @@
     };
     STRUCT_COPY_FROM_STRUCT(return_encoding, base_encoding);
     Parrot_register_encoding(interp, "utf16", return_encoding);
-    return return_encoding;
+
+    return;
 }
 
 /*

Modified: trunk/src/string/encoding/utf16.h
==============================================================================
--- trunk/src/string/encoding/utf16.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/utf16.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -16,8 +16,7 @@
 /* HEADERIZER BEGIN: src/string/encoding/utf16.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING * Parrot_encoding_utf16_init(PARROT_INTERP)
+void Parrot_encoding_utf16_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_Parrot_encoding_utf16_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/string/encoding/utf8.c
==============================================================================
--- trunk/src/string/encoding/utf8.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/utf8.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -27,17 +27,13 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void become_encoding(PARROT_INTERP, SHIM(STRING *src))
-        __attribute__nonnull__(1);
-
 PARROT_PURE_FUNCTION
-static UINTVAL bytes(SHIM_INTERP, ARGIN(STRING *src))
+static UINTVAL bytes(SHIM_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(2);
 
-static UINTVAL codepoints(PARROT_INTERP, ARGMOD(STRING *src))
+static UINTVAL codepoints(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*src);
+        __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
 static UINTVAL find_cclass(PARROT_INTERP,
@@ -62,14 +58,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*src);
 
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_bytes_inplace(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *return_string))
-        __attribute__nonnull__(1);
-
 static UINTVAL get_codepoint(PARROT_INTERP,
     ARGIN(const STRING *src),
     UINTVAL offset)
@@ -84,18 +72,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_CANNOT_RETURN_NULL
-static STRING * get_codepoints_inplace(PARROT_INTERP,
-    ARGMOD(STRING *src),
-    UINTVAL offset,
-    UINTVAL count,
-    ARGMOD(STRING *return_string))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*src)
-        FUNC_MODIFIES(*return_string);
-
 static void iter_init(SHIM_INTERP,
     ARGIN(const STRING *src),
     ARGOUT(String_iter *iter))
@@ -110,35 +86,10 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void set_bytes(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *new_bytes))
-        __attribute__nonnull__(1);
-
-static void set_codepoint(PARROT_INTERP,
-    ARGIN(STRING *src),
-    UINTVAL offset,
-    UINTVAL codepoint)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void set_codepoints(PARROT_INTERP,
-    SHIM(STRING *src),
-    SHIM(UINTVAL offset),
-    SHIM(UINTVAL count),
-    SHIM(STRING *new_codepoints))
-        __attribute__nonnull__(1);
-
 PARROT_CAN_RETURN_NULL
-static STRING * to_encoding(PARROT_INTERP,
-    ARGMOD(STRING *src),
-    ARGMOD_NULLOK(STRING *dest))
+static STRING * to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*src)
-        FUNC_MODIFIES(*dest);
+        __attribute__nonnull__(2);
 
 static UINTVAL utf8_characters(PARROT_INTERP,
     ARGIN(const utf8_t *ptr),
@@ -183,8 +134,6 @@
 static const void * utf8_skip_forward(ARGIN(const void *ptr), UINTVAL n)
         __attribute__nonnull__(1);
 
-#define ASSERT_ARGS_become_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -197,31 +146,18 @@
 #define ASSERT_ARGS_get_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_get_bytes_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_get_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
 #define ASSERT_ARGS_get_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_get_codepoints_inplace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src) \
-    , PARROT_ASSERT_ARG(return_string))
 #define ASSERT_ARGS_iter_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(src) \
     , PARROT_ASSERT_ARG(iter))
 #define ASSERT_ARGS_set_byte __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_set_bytes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_set_codepoint __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(src))
-#define ASSERT_ARGS_set_codepoints __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_to_encoding __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(src))
@@ -271,10 +207,6 @@
     4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6      /* cjk etc. */
 };
 
-#if 0
-typedef unsigned char utf8_t;
-#endif
-
 /*
 
 =item C<static UINTVAL utf8_characters(PARROT_INTERP, const utf8_t *ptr, UINTVAL
@@ -566,7 +498,7 @@
 
 /*
 
-=item C<static STRING * to_encoding(PARROT_INTERP, STRING *src, STRING *dest)>
+=item C<static STRING * to_encoding(PARROT_INTERP, const STRING *src)>
 
 Converts the string C<src> to this particular encoding.  If C<dest> is
 provided, it will contain the result.  Otherwise this function operates in
@@ -578,24 +510,19 @@
 
 PARROT_CAN_RETURN_NULL
 static STRING *
-to_encoding(PARROT_INTERP, ARGMOD(STRING *src), ARGMOD_NULLOK(STRING *dest))
+to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(to_encoding)
     STRING *result;
     String_iter src_iter;
     UINTVAL offs, dest_len, dest_pos, src_len;
-    const int in_place = (dest == NULL);
     unsigned char *p;
 
     if (src->encoding == Parrot_utf8_encoding_ptr)
-        return in_place ? src : Parrot_str_copy(interp, src);
+        return Parrot_str_clone(interp, src);
+
+    result = Parrot_gc_new_string_header(interp, 0);
     src_len = src->strlen;
-    if (in_place) {
-        result = src;
-    }
-    else {
-        result = dest;
-    }
 
     /* init iter before possilby changing encoding */
     ENCODING_ITER_INIT(interp, src, &src_iter);
@@ -604,16 +531,11 @@
     result->strlen   = src_len;
 
     if (!src->strlen)
-        return dest;
+        return result;
+
+    Parrot_gc_allocate_string_storage(interp, result, src_len);
+    p = (unsigned char *)result->strstart;
 
-    if (in_place) {
-        /* need intermediate memory */
-        p = mem_gc_allocate_n_typed(interp, src_len, unsigned char);
-    }
-    else {
-        Parrot_gc_reallocate_string_storage(interp, dest, src_len);
-        p = (unsigned char *)dest->strstart;
-    }
     if (src->charset == Parrot_ascii_charset_ptr) {
         for (dest_len = 0; dest_len < src_len; ++dest_len) {
             p[dest_len] = ((unsigned char*)src->strstart)[dest_len];
@@ -633,13 +555,9 @@
                 if (need < 16)
                     need = 16;
                 dest_len += need;
-                if (in_place)
-                    p = mem_gc_realloc_n_typed(interp, p, dest_len, unsigned char);
-                else {
-                    result->bufused = dest_pos;
-                    Parrot_gc_reallocate_string_storage(interp, dest, dest_len);
-                    p = (unsigned char *)dest->strstart;
-                }
+                result->bufused = dest_pos;
+                Parrot_gc_reallocate_string_storage(interp, result, dest_len);
+                p = (unsigned char *)result->strstart;
             }
 
             pos = p + dest_pos;
@@ -648,11 +566,7 @@
         }
         result->bufused = dest_pos;
     }
-    if (in_place) {
-        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
-        memcpy(src->strstart, p, src->bufused);
-        mem_gc_free(interp, p);
-    }
+
     return result;
 }
 
@@ -675,29 +589,6 @@
     return utf8_decode(interp, start);
 }
 
-/*
-
-=item C<static void set_codepoint(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL codepoint)>
-
-Sets, in string C<src> at position C<offset>, the codepoint C<codepoint>.
-
-=cut
-
-*/
-
-static void
-set_codepoint(PARROT_INTERP, ARGIN(STRING *src), UINTVAL offset, UINTVAL codepoint)
-{
-    ASSERT_ARGS(set_codepoint)
-    const void *start;
-    void *p;
-    DECL_CONST_CAST;
-
-    start = utf8_skip_forward(src->strstart, offset);
-    p = PARROT_const_cast(void *, start);
-    utf8_encode(interp, p, codepoint);
-}
 
 /*
 
@@ -789,7 +680,7 @@
 {
     ASSERT_ARGS(get_codepoints)
 
-    STRING * const return_string = Parrot_str_new_COW(interp, src);
+    STRING * const return_string = Parrot_str_copy(interp, src);
     String_iter    iter;
     UINTVAL        start;
 
@@ -827,10 +718,7 @@
 get_bytes(PARROT_INTERP, ARGMOD(STRING *src), UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(get_bytes)
-    STRING * const return_string = Parrot_str_new_COW(interp, src);
-
-    return_string->encoding = src->encoding;    /* XXX */
-    return_string->charset = src->charset;
+    STRING * const return_string = Parrot_str_copy(interp, src);
 
     return_string->strstart = (char *)return_string->strstart + offset ;
     return_string->bufused = count;
@@ -841,125 +729,11 @@
     return return_string;
 }
 
-/*
-
-=item C<static STRING * get_codepoints_inplace(PARROT_INTERP, STRING *src,
-UINTVAL offset, UINTVAL count, STRING *return_string)>
-
-Gets from string C<src> at position C<offset> C<count> codepoints and returns
-them in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_codepoints_inplace(PARROT_INTERP, ARGMOD(STRING *src),
-        UINTVAL offset, UINTVAL count, ARGMOD(STRING *return_string))
-{
-    ASSERT_ARGS(get_codepoints_inplace)
-    String_iter iter;
-    UINTVAL start;
-
-    Parrot_str_reuse_COW(interp, src, return_string);
-    iter_init(interp, src, &iter);
-    iter.set_position(interp, &iter, offset);
-
-    start = iter.bytepos;
-
-    return_string->strstart = (char *)return_string->strstart + start;
-    iter.set_position(interp, &iter, offset + count);
-
-    return_string->bufused = iter.bytepos - start;
-    return_string->strlen  = count;
-    return_string->hashval = 0;
-
-    return return_string;
-}
-
-/*
-
-=item C<static STRING * get_bytes_inplace(PARROT_INTERP, STRING *src, UINTVAL
-offset, UINTVAL count, STRING *return_string)>
-
-Gets from string C<src> at position C<offset> C<count> bytes and returns them
-in C<return_string>.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-static STRING *
-get_bytes_inplace(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *return_string))
-{
-    ASSERT_ARGS(get_bytes_inplace)
-    UNIMPL;
-}
-
-/*
-
-=item C<static void set_codepoints(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL count, STRING *new_codepoints)>
-
-Replaces in string C<src> at position C<offset> for C<count> codepoints with
-the contents of string C<new_codepoints>.
-
-=cut
-
-*/
-
-static void
-set_codepoints(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_codepoints))
-{
-    ASSERT_ARGS(set_codepoints)
-    UNIMPL;
-}
-
-/*
-
-=item C<static void set_bytes(PARROT_INTERP, STRING *src, UINTVAL offset,
-UINTVAL count, STRING *new_bytes)>
-
-Replaces in string C<src> at position C<offset> for C<count> bytes with the
-contents of string C<new_bytes>.
-
-=cut
-
-*/
-
-static void
-set_bytes(PARROT_INTERP, SHIM(STRING *src),
-        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_bytes))
-{
-    ASSERT_ARGS(set_bytes)
-    UNIMPL;
-}
-
-/*
-
-=item C<static void become_encoding(PARROT_INTERP, STRING *src)>
-
-Unconditionally makes the string be in this encoding, if that's valid
-
-=cut
-
-*/
-
-static void
-become_encoding(PARROT_INTERP, SHIM(STRING *src))
-{
-    ASSERT_ARGS(become_encoding)
-    UNIMPL;
-}
 
 
 /*
 
-=item C<static UINTVAL codepoints(PARROT_INTERP, STRING *src)>
+=item C<static UINTVAL codepoints(PARROT_INTERP, const STRING *src)>
 
 Returns the number of codepoints in string C<src>.
 
@@ -968,7 +742,7 @@
 */
 
 static UINTVAL
-codepoints(PARROT_INTERP, ARGMOD(STRING *src))
+codepoints(PARROT_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(codepoints)
     String_iter iter;
@@ -984,7 +758,7 @@
 
 /*
 
-=item C<static UINTVAL bytes(PARROT_INTERP, STRING *src)>
+=item C<static UINTVAL bytes(PARROT_INTERP, const STRING *src)>
 
 Returns the number of bytes in string C<src>.
 
@@ -994,7 +768,7 @@
 
 PARROT_PURE_FUNCTION
 static UINTVAL
-bytes(SHIM_INTERP, ARGIN(STRING *src))
+bytes(SHIM_INTERP, ARGIN(const STRING *src))
 {
     ASSERT_ARGS(bytes)
     return src->bufused;
@@ -1025,7 +799,7 @@
 
 /*
 
-=item C<ENCODING * Parrot_encoding_utf8_init(PARROT_INTERP)>
+=item C<void Parrot_encoding_utf8_init(PARROT_INTERP)>
 
 Initializes the UTF-8 encoding.
 
@@ -1033,8 +807,7 @@
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING *
+void
 Parrot_encoding_utf8_init(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_encoding_utf8_init)
@@ -1045,16 +818,10 @@
         4, /* Max bytes per codepoint 0 .. 0x10ffff */
         to_encoding,
         get_codepoint,
-        set_codepoint,
         get_byte,
         set_byte,
         get_codepoints,
-        get_codepoints_inplace,
         get_bytes,
-        get_bytes_inplace,
-        set_codepoints,
-        set_bytes,
-        become_encoding,
         codepoints,
         bytes,
         iter_init,
@@ -1063,7 +830,8 @@
     };
     STRUCT_COPY_FROM_STRUCT(return_encoding, base_encoding);
     Parrot_register_encoding(interp, "utf8", return_encoding);
-    return return_encoding;
+
+    return;
 }
 
 /*

Modified: trunk/src/string/encoding/utf8.h
==============================================================================
--- trunk/src/string/encoding/utf8.h	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/encoding/utf8.h	Wed Apr 21 10:06:00 2010	(r45852)
@@ -16,8 +16,7 @@
 /* HEADERIZER BEGIN: src/string/encoding/utf8.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-ENCODING * Parrot_encoding_utf8_init(PARROT_INTERP)
+void Parrot_encoding_utf8_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_Parrot_encoding_utf8_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/string/primitives.c
==============================================================================
--- trunk/src/string/primitives.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/string/primitives.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -70,8 +70,8 @@
 
 /*
 
-=item C<Parrot_UInt4 string_unescape_one(PARROT_INTERP, UINTVAL *offset, STRING
-*string)>
+=item C<Parrot_UInt4 string_unescape_one(PARROT_INTERP, UINTVAL *offset, const
+STRING *string)>
 
 Unescape a single character. We assume that we're at the start of a
 sequence, right after the \.
@@ -83,7 +83,7 @@
 PARROT_EXPORT
 Parrot_UInt4
 string_unescape_one(PARROT_INTERP, ARGMOD(UINTVAL *offset),
-        ARGMOD(STRING *string))
+        ARGIN(const STRING *string))
 {
     ASSERT_ARGS(string_unescape_one)
     UINTVAL workchar  = 0;

Modified: trunk/src/sub.c
==============================================================================
--- trunk/src/sub.c	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/src/sub.c	Wed Apr 21 10:06:00 2010	(r45852)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2009, Parrot Foundation.
+Copyright (C) 2001-2010, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -395,7 +395,7 @@
         PMC * const lex_pad = Parrot_pcc_get_lex_pad(interp, ctx);
         PMC * outer         = Parrot_pcc_get_outer_ctx(interp, ctx);
 
-        if (!outer)
+        if (PMC_IS_NULL(outer))
             return lex_pad;
 
         if (!PMC_IS_NULL(lex_pad))
@@ -428,7 +428,7 @@
         PMC * const lex_pad = Parrot_pcc_get_lex_pad(interp, ctx);
         PMC * caller        = Parrot_pcc_get_caller_ctx(interp, ctx);
 
-        if (!caller)
+        if (PMC_IS_NULL(caller))
             return lex_pad;
 
         if (!PMC_IS_NULL(lex_pad))
@@ -633,10 +633,6 @@
 
 F<include/parrot/sub.h>.
 
-=head1 HISTORY
-
-Initial version by Melvin on 2002/06/6.
-
 =cut
 
 */

Modified: trunk/t/native_pbc/annotations.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/integer_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/string_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/op/string.t
==============================================================================
--- trunk/t/op/string.t	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/t/op/string.t	Wed Apr 21 10:06:00 2010	(r45852)
@@ -19,7 +19,7 @@
 .sub main :main
     .include 'test_more.pir'
 
-    plan(412)
+    plan(399)
 
     set_s_s_sc()
     test_clone()
@@ -27,7 +27,6 @@
     test_length_i_s()
     zero_length_substr()
     chopn_with_clone()
-    chopn_with_set()
     chopn_oob_values()
     three_argument_chopn()
     three_argument_chopn__oob_values()
@@ -40,6 +39,7 @@
     five_arg_substr_w_rep_eq_length()
     five_arg_substr_w_replacement_gt_length()
     five_arg_substr_w_replacement_lt_length()
+    five_arg_substr_vs_hash()
     five_arg_substr__offset_at_end_of_string()
     exception_five_arg_substr__offset_past_end_of_string()
     five_arg_substr_neg_offset_repl_eq_length()
@@ -122,10 +122,8 @@
     correct_precision_for_sprintf_x()
     test_exchange()
     test_find_encoding()
-    test_string_encoding()
     test_assign()
     assign_and_globber()
-    assign_and_globber_2()
     bands_null_string()
     bands_2()
     bands_3()
@@ -141,8 +139,6 @@
     bnots_null_string()
     bnots_2()
     bnots_cow()
-    transcode_to_utf8()
-    string_chartype()
     split_on_empty_string()
     split_on_non_empty_string()
     test_join()
@@ -237,20 +233,6 @@
     is( $S3, "JAPHxyzw", '' )
 .end
 
-.sub chopn_with_set
-    set $S4, "JAPHxyzw"
-    set $S5, "japhXYZW"
-    set     $S3, $S4
-    set $I1, 4
-    chopn   $S4, 3
-    chopn   $S4, 1
-    chopn   $S5, $I1
-
-    is( $S4, "JAPH", '' )
-    is( $S5, "japh", '' )
-    is( $S3, "JAPH", '' )
-.end
-
 .sub chopn_oob_values
     set $S1, "A string of length 21"
     chopn   $S1, 0
@@ -292,10 +274,6 @@
     set     $S3, $S1
     chopn   $S2, $S1, 3
     is( $S3, "Parrot", '' )
-
-    set     $S3, $S1
-    chopn   $S1, 3
-    is( $S3, "Par", '' )
 .end
 #
 .sub three_argument_chopn__oob_values
@@ -427,6 +405,18 @@
     is( $S2, "", '' )
 .end
 
+.sub five_arg_substr_vs_hash
+    # Check that string hashval properly updated.
+    .local pmc hash
+    hash = new ['Hash']
+    $S0 = "fooo"
+    hash[$S0]   = 1
+    hash["foo"] = 42
+    $S0 = replace $S0, 1, 1, ''
+    $S1 = hash[$S0]
+    is( $S1, '42', 'substr behave it self')
+.end
+
 .sub exception_five_arg_substr__offset_past_end_of_string
     set $S0, "abcdefghijk"
     set $S1, "xyz"
@@ -434,7 +424,7 @@
     substr $S2, $S0, 12, 3, $S1
     ok(0,"no exception")
 handler:
-    .exception_is( "Can only replace inside string or index after end of string" )
+    .exception_is( "Cannot take substr outside string" )
 .end
 
 .sub five_arg_substr_neg_offset_repl_eq_length
@@ -471,7 +461,7 @@
     substr $S2, $S0, -12, 4, $S1
     ok(0,"no exception")
 handler:
-    .exception_is( "Can only replace inside string or index after end of string" )
+    .exception_is( "Cannot take substr outside string" )
 .end
 
 .sub five_arg_substr_length_gt_strlen
@@ -495,9 +485,10 @@
 .sub four_arg_replacement_only_substr
     set $S0, "abcdefghijk"
     set $S1, "xyz"
-    substr $S0, 3, 3, $S1
-    is( $S0, "abcxyzghijk", '' )
+    $S2 = replace $S0, 3, 3, $S1
+    is( $S0, "abcdefghijk", '' )
     is( $S1, "xyz", '' )
+    is( $S2, "abcxyzghijk", '' )
 .end
 
 .sub three_arg_substr
@@ -1477,34 +1468,6 @@
     # is( $I0, "3", 'find_encoding' )
 .end
 
-.sub test_string_encoding
-    skip(4, "no more visible encoding" )
-    # set $I0, 0
-    # new $S0, 0, $I0
-    # string_encoding $I1, $S0
-    # eq $I0, $I1, OK1
-    # print "not "
-    # OK1:  print "ok 1\n"
-    # set $I0, 1
-    # new $S0, 0, $I0
-    # string_encoding $I1, $S0
-    # eq $I0, $I1, OK2
-    # print "not "
-    # OK2:  print "ok 2\n"
-    # set $I0, 2
-    # new $S0, 0, $I0
-    # string_encoding $I1, $S0
-    # eq $I0, $I1, OK3
-    # print "not "
-    # OK3:  print "ok 3\n"
-    # set $I0, 3
-    # new $S0, 0, $I0
-    # string_encoding $I1, $S0
-    # eq $I0, $I1, OK4
-    # print "not "
-    # OK4:  print "ok 4\n"
-.end
-
 .sub test_assign
     set $S4, "JAPH"
     assign  $S5, $S4
@@ -1520,14 +1483,6 @@
     is( $S5, "JAPH", 'assign & globber' )
 .end
 
-.sub assign_and_globber_2
-    set $S4, "JAPH"
-    set     $S5, $S4
-    assign  $S4, "Parrot"
-    is( $S4, "Parrot", 'assign & globber 2' )
-    is( $S5, "Parrot", 'assign & globber 2' )
-.end
-
 .sub bands_null_string
     null $S1
     set $S2, "abc"
@@ -1768,25 +1723,6 @@
     is( $S2, "foo", 'bnots COW' )
 .end
 
-.sub transcode_to_utf8
-    skip( 2, "no more transcode" )
-    # set $S1, "ASCII is the same as UTF8\n"
-    # find_encoding $I1, "utf8"
-    # transcode $S2, $S1, $I1
-    # is( $S1, "ASCII is the same as UTF8", 'transcode to utf8' )
-    # is( $S2, "ASCII is the same as UTF8", 'transcode to utf8' )
-.end
-
-.sub string_chartype
-    skip( 1, "no more chartype" )
-
-    # set $S0, "Test String"
-    # find_chartype $I0, "usascii"
-    # set_chartype $S0, $I0
-    # string_chartype $I1, $S0
-    # is( $I0, $I1, 'string_chartype' )
-.end
-
 .sub split_on_empty_string
     split $P1, "", ""
     set $I1, $P1
@@ -1865,19 +1801,6 @@
   OK1:
     ok($I99, 'eq_addr/ne_addr')
 
-    set $S1, "Test"
-    set $I99, 0
-    eq_addr $S1, $S0, BAD2
-      set $I99, 1
-  BAD2:
-    ok($I99, 'eq_addr/ne_addr')
-
-    set $I99, 1
-    ne_addr $S1, $S0, OK3
-      set $I99, 0
-  OK3:
-    ok($I99, 'eq_addr/ne_addr')
-
     set $S0, $S1
     set $I99, 0
     ne_addr $S1, $S0, BAD4

Modified: trunk/t/pmc/string.t
==============================================================================
--- trunk/t/pmc/string.t	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/t/pmc/string.t	Wed Apr 21 10:06:00 2010	(r45852)
@@ -20,14 +20,13 @@
 .sub main :main
     .include 'test_more.pir'
 
-    plan(173)
+    plan(171)
 
     set_or_get_strings()
     setting_integers()
     setting_numbers()
     ensure_that_concat_ppp_copies_strings()
     ensure_that_concat_pps_copies_strings()
-    setting_string_references()
     assigning_string_copies()
     test_repeat()
     test_repeat_without_creating_dest_pmc()
@@ -203,16 +202,6 @@
     is( $P0, 'fnarghGrunties', 'concat success' )
 .end
 
-.sub setting_string_references
-    new $P0, ['String']
-    set $S0, "C2H5OH + 10H20"
-    set $P0, $S0
-    chopn $S0, 8
-
-    is( $S0, 'C2H5OH', 'removed last 8 from string' )
-    is( $P0, 'C2H5OH', '...and the PMC still reference $S0' )
-.end
-
 .sub assigning_string_copies
     new $P0, ['String']
     set $S0, "C2H5OH + 10H20"

Modified: trunk/tools/dev/pbc_to_exe.pir
==============================================================================
--- trunk/tools/dev/pbc_to_exe.pir	Wed Apr 21 10:05:57 2010	(r45851)
+++ trunk/tools/dev/pbc_to_exe.pir	Wed Apr 21 10:06:00 2010	(r45852)
@@ -307,10 +307,13 @@
     .local pmc encoding_table
     encoding_table = 'generate_encoding_table'()
 
-    .local string codestring
+    .local pmc codestring
     .local int size
-    codestring = "const char * program_code =\n"
-    codestring .= '"'
+
+    codestring = new ['ResizableStringArray']
+
+    push codestring, "const char * program_code =\n"
+    push codestring, '"'
     size = 0
 
   read_loop:
@@ -327,14 +330,14 @@
     unless pos < pbclength goto code_done
     $I0 = ord pbcstring, pos
     $S0 = encoding_table[$I0]
-    codestring .= $S0
+    push codestring, $S0
     inc pos
     inc size
     $I0 = size % 32
     unless $I0 == 0 goto code_loop
-    codestring .= '"'
-    codestring .= "\n"
-    codestring .= '"'
+    push codestring, '"'
+    push codestring, "\n"
+    push codestring, '"'
     goto code_loop
   code_done:
     goto read_loop
@@ -342,21 +345,22 @@
   read_done:
     close ifh
 
-    codestring .= '"'
-    codestring .= "\n;\n\n"
-    codestring .= "const int bytecode_size = "
+    push codestring, '"'
+    push codestring, "\n;\n\n"
+    push codestring, "const int bytecode_size = "
     $S0 = size
-    codestring .= $S0
-    codestring .= ";\n"
+    push codestring, $S0
+    push codestring, ";\n"
 
-    codestring .= <<'END_OF_FUNCTION'
+    push codestring, <<'END_OF_FUNCTION'
         const void * get_program_code(void)
         {
             return program_code;
         }
 END_OF_FUNCTION
 
-    .return (codestring)
+    $S0 = join '', codestring
+    .return ($S0)
 
   err_infile:
     die "cannot open infile"


More information about the parrot-commits mailing list