I've made some more work on this patch. First, fixed an error that
breaks pdb build. Then, replacing the string_to_cstring function in a
lot more places, and adding a new packfile function to find the
location of a label without strings copying. The latter gives a
noticeable speedup. I'm not sure about the correctness of the packfile
usage, but all test pass in my system, Linux i386.

-- 
Salu2
Index: src/pdb.c
===================================================================
--- src/pdb.c	(revisión: 28225)
+++ src/pdb.c	(copia de trabajo)
@@ -219,9 +219,8 @@
     Parrot_exception exp;
 
     if (setjmp(exp.destination)) {
-        char *msg = string_to_cstring(interp, interp->exceptions->msg);
-        fprintf(stderr, "Caught exception: %s\n", msg);
-        string_cstring_free(msg);
+        fprintf(stderr, "Caught exception: %s\n",
+            Parrot_string_get_cstring(interp, interp->exceptions->msg));
         return;
     }
 
Index: src/oo.c
===================================================================
--- src/oo.c	(revisión: 28225)
+++ src/oo.c	(copia de trabajo)
@@ -405,7 +405,7 @@
 INTVAL
 Parrot_get_vtable_index(PARROT_INTERP, ARGIN(const STRING *name))
 {
-    char * const name_c      = string_to_cstring(interp, name);
+    const char * const name_c = Parrot_string_get_cstring(interp, name);
 
     /* some of the first "slots" don't have names. skip 'em. */
     INTVAL low               = PARROT_VTABLE_LOW;
@@ -419,7 +419,6 @@
         const INTVAL cmp = strcmp(name_c, meth_c + 2);
 
         if (cmp == 0) {
-            string_cstring_free(name_c);
             return mid;
         }
         else if (cmp > 0)
@@ -428,8 +427,6 @@
             high = mid;
     }
 
-    string_cstring_free(name_c);
-
     return -1;
 }
 
Index: src/hll.c
===================================================================
--- src/hll.c	(revisión: 28225)
+++ src/hll.c	(copia de trabajo)
@@ -93,7 +93,7 @@
 
     if (entry_name && !STRING_IS_EMPTY(entry_name)) {
         STRING *const_name = const_string(interp,
-            string_to_cstring(interp, entry_name));
+            Parrot_string_get_cstring(interp, entry_name));
 
         VTABLE_set_pmc_keyed_str(interp, hll_info, const_name, entry);
     }
Index: src/ops/debug.ops
===================================================================
--- src/ops/debug.ops	(revisión: 28225)
+++ src/ops/debug.ops	(copia de trabajo)
@@ -64,12 +64,10 @@
 =cut
 
 op debug_load(inconst STR) :base_debug {
-    char *f;
 
     if (!(interp->pdb->state & PDB_BREAK)) {
-        f = string_to_cstring(interp, ($1));
+        const char * f = Parrot_string_get_cstring(interp, ($1));
         PDB_load_source(interp, f);
-        string_cstring_free(f);
     }
 }
 
Index: src/ops/core.ops
===================================================================
--- src/ops/core.ops	(revisión: 28225)
+++ src/ops/core.ops	(copia de trabajo)
@@ -185,21 +185,13 @@
 =cut
 
 inline op branch_cs(in STR) :base_loop :check_event :flow {
-    char * const         label = string_to_cstring(interp, $1);
-    PackFile_FixupEntry * const fe =
-        PackFile_find_fixup_entry(interp, enum_fixup_label, label);
-
-    if (!fe) {
-        string_cstring_free(label);
+    const char * const label = Parrot_string_get_cstring(interp, $1);
+    PackFile_FixupEntryData fe;
+    if (! PackFile_find_fixup_entry_data(interp, enum_fixup_label, label, & fe) )
         real_exception(interp, NULL, 1, "branch_cs: fixup for '%Ss' not found",
             $1);
-    }
-    else {
-        interp->resume_offset = fe->offset;
-        Parrot_switch_to_cs(interp, fe->seg, 1);
-    }
-    mem_sys_free(fe);
-    string_cstring_free(label);
+    interp->resume_offset = fe.offset;
+    Parrot_switch_to_cs(interp, fe.seg, 1);
     interp->resume_flag = 2;
     goto ADDRESS(0);
 }
@@ -1244,7 +1236,7 @@
 }
 
 op dlfunc(out PMC, invar PMC, in STR, in STR) {
-    char * const name = string_to_cstring(interp, ($3));
+    const char * const name = Parrot_string_get_cstring(interp, ($3));
     void *ptr         = Parrot_dlsym(
                             PMC_IS_NULL($2) ? NULL :
                             VTABLE_defined(interp, $2) ? PMC_data($2) :
@@ -1264,13 +1256,11 @@
         VTABLE_set_pointer_keyed_str(interp, $1, $4, F2DPTR(p));
         PObj_get_FLAGS($1) |= PObj_private1_FLAG;
     }
-    string_cstring_free(name);
 }
 
 op dlvar(out PMC, invar PMC, in STR) {
-    char * const name = string_to_cstring(interp, ($3));
+    const char * const name = Parrot_string_get_cstring(interp, ($3));
     void * const p = Parrot_dlsym(PMC_IS_NULL($2) ? NULL : PMC_data($2), name);
-    string_cstring_free(name);
     if (p == NULL) {
         const char * const err = Parrot_dlerror();
         Parrot_warn(interp, PARROT_WARNINGS_UNDEF_FLAG,
Index: src/ops/io.ops
===================================================================
--- src/ops/io.ops	(revisión: 28225)
+++ src/ops/io.ops	(copia de trabajo)
@@ -54,18 +54,11 @@
 
 inline op fdopen(out PMC, in INT, in STR) :filesys_open {
     /* These char * need to go away soon */
-    char * const mode = string_to_cstring(interp, $3);
+    const char * const mode = Parrot_string_get_cstring(interp, $3);
 
     $1 = PIO_fdopen(interp, NULL, (PIOHANDLE)$2, mode);
     if (!$1)
         $1 = pmc_new(interp, enum_class_Undef);
-
-    /* RT#42374 all results from string_to_cstring() need freeing
-     but this generates ugly warnings WRT discarding the const
-     qualifier -lt
-    */
-
-    string_cstring_free(mode);
 }
 
 =item B<getfd>(out INT, invar PMC)
@@ -141,24 +134,20 @@
 
 inline op open(out PMC, in STR, in STR) :filesys_open {
     /* These char * need to go away soon */
-    char * const path = string_to_cstring(interp, $2);
-    char * const mode = string_to_cstring(interp, $3);
+    const char * const path = Parrot_string_get_cstring(interp, $2);
+    const char * const mode = Parrot_string_get_cstring(interp, $3);
 
     $1 = PIO_open(interp, NULL, path, mode);
 
-    string_cstring_free(mode);
-    string_cstring_free(path);
-
     if (!$1 || !PMC_struct_val($1))
         $1 = pmc_new(interp, enum_class_Undef);
 }
 
 inline op open(out PMC, in STR) :filesys_open {
     /* These char * need to go away soon */
-    char * const path = string_to_cstring(interp, $2);
+    const char * const path = Parrot_string_get_cstring(interp, $2);
 
     $1 = PIO_open(interp, NULL, path, "+<");
-    string_cstring_free(path);
     if (!$1)
         $1 = pmc_new(interp, enum_class_Undef);
 }
Index: src/global.c
===================================================================
--- src/global.c	(revisión: 28225)
+++ src/global.c	(copia de trabajo)
@@ -725,7 +725,6 @@
 store_sub_in_multi(PARROT_INTERP, ARGIN(PMC *sub), ARGIN(PMC *ns))
 {
     INTVAL func_nr;
-    char   *c_meth;
     STRING * const subname = PMC_sub(sub)->name;
     PMC    *multisub = VTABLE_get_pmc_keyed_str(interp, ns, subname);
 
@@ -740,11 +739,10 @@
     else
         VTABLE_push_pmc(interp, multisub, sub);
 
-    c_meth  = string_to_cstring(interp, subname);
-    func_nr = Parrot_MMD_method_idx(interp, c_meth);
+    func_nr = Parrot_MMD_method_idx(interp,
+        Parrot_string_get_cstring(interp, subname));
     if (func_nr >= 0)
         Parrot_mmd_rebuild_table(interp, -1, func_nr);
-    string_cstring_free(c_meth);
 }
 
 /*
Index: src/gc/dod.c
===================================================================
--- src/gc/dod.c	(revisión: 28225)
+++ src/gc/dod.c	(copia de trabajo)
@@ -625,6 +625,9 @@
                 }
 #endif
 
+                if (PObj_is_string_TEST(b))
+                    Parrot_string_free_cstring(interp, (STRING *) (b));
+
                 if (PObj_is_shared_TEST(b)) {
                     /* only mess with shared objects if we
                      * (and thus everyone) is suspended for
Index: src/string.c
===================================================================
--- src/string.c	(revisión: 28225)
+++ src/string.c	(copia de trabajo)
@@ -153,6 +153,8 @@
         PObj_COW_SET(s);
         STRUCT_COPY(d, s);
         PObj_sysmem_CLEAR(d);
+        if (! PObj_external_TEST(d))
+            d->cstring_val = NULL;
 #if 0
         /* XXX FIXME hack to avoid cross-interpreter issue until it
          * is fixed correctly. */
@@ -198,6 +200,8 @@
         PObj_COW_SET(s);
         STRUCT_COPY(d, s);
         PObj_sysmem_CLEAR(d);
+        if (! PObj_external_TEST(s))
+            d->cstring_val = NULL;
     }
     return d;
 }
@@ -511,6 +515,7 @@
     if (a == NULL || PObj_bufstart(a) == NULL)
         return string_copy(interp, b);
 
+    Parrot_string_free_cstring(interp, a);
     saneify_string(a);
     saneify_string(b);
 
@@ -1037,8 +1042,10 @@
     dest->bufused = s->bufused * num;
     dest->strlen  = s->strlen * num;
 
-    if (d != NULL)
+    if (d != NULL) {
+        Parrot_string_free_cstring(interp, * d);
         *d = dest;
+    }
 
     return dest;
 }
@@ -1166,6 +1173,9 @@
         return NULL;
     }
 
+    if (d)
+        Parrot_string_free_cstring(interp, * d);
+
     /* abs(-offset) may not be > strlen-1 */
     if (offset < 0)
         true_offset = (UINTVAL)(src->strlen + offset);
@@ -2061,6 +2071,14 @@
 void
 string_cstring_free(ARGIN_NULLOK(char *p))
 {
+#ifndef NDEBUG
+    {
+        if (p) {
+            int l= strlen(p);
+            memset(p, '!', l);
+        }
+    }
+#endif
     mem_sys_free((void *)p);
 }
 
@@ -2637,6 +2655,57 @@
 
 /*
 
+=item C<const char * Parrot_string_free_cstring>
+
+Free the cached C string created by Parrot_string_get_string,
+called when the Parrot string is deleted or modified.
+
+*/
+
+PARROT_API
+void
+Parrot_string_free_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *str))
+{
+    if (str && ! (PObj_external_TEST(str) || PObj_constant_TEST(str))
+            && str->cstring_val) {
+        DECL_CONST_CAST;
+        STRING * strmut = PARROT_const_cast(STRING *, str);
+        string_cstring_free(PARROT_const_cast(char *, strmut->cstring_val));
+        strmut->cstring_val = NULL;
+    }
+}
+
+/*
+
+=item C<const char * Parrot_string_get_cstring>
+
+Convert a Parrot string to a C string. The C string is owned by
+the Parrot string, and is valid until the Parrot string is modified.
+
+=cut
+
+*/
+
+PARROT_API
+const char *
+Parrot_string_get_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *str))
+{
+    if (! str)
+        return NULL;
+
+    if (PObj_external_TEST(str) || PObj_constant_TEST(str))
+        return str->strstart;
+
+    if (! str->cstring_val) {
+        DECL_CONST_CAST;
+        STRING * strmut = PARROT_const_cast(STRING *, str);
+        strmut->cstring_val = string_to_cstring(interp, str);
+    }
+    return str->cstring_val;
+}
+
+/*
+
 =item C<INTVAL Parrot_string_is_cclass>
 
 Returns 1 if the codepoint of string C<s> at given offset is in the given
Index: src/pmc/os.pmc
===================================================================
--- src/pmc/os.pmc	(revisión: 28225)
+++ src/pmc/os.pmc	(copia de trabajo)
@@ -109,13 +109,12 @@
 
     METHOD chdir(STRING *path) {
         int error;
-        char * const cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
 #ifdef _MSC_VER
         error = _chdir(cpath);
 #else
         error = chdir(cpath);
 #endif
-        string_cstring_free(cpath);
         if (error) {
             char *errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -135,12 +134,11 @@
 
     METHOD rm(STRING *path) {
         struct stat info;
-        char *cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
         int   error = stat(cpath, &info);
 
         if (error) {
             const char * const errmsg = strerror(errno);
-            string_cstring_free(cpath);
             real_exception(interp, NULL, E_SystemError, errmsg);
         }
 
@@ -150,7 +148,6 @@
 #else
             error = rmdir(cpath);
 #endif
-            string_cstring_free(cpath);
             if (error) {
                 const char * const errmsg = strerror(errno);
                 real_exception(interp, NULL, E_SystemError, errmsg);
@@ -158,7 +155,6 @@
         }
         else {
             error = remove(cpath);
-            string_cstring_free(cpath);
             if (error) {
                 const char * const errmsg = strerror(errno);
                 real_exception(interp, NULL, E_SystemError, errmsg);
@@ -178,14 +174,13 @@
 
     METHOD mkdir(STRING *path, INTVAL mode) {
         int   error;
-        char * const cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
         /* should we validate mode? */
 #ifdef WIN32
         error = _mkdir(cpath);
 #else
         error = mkdir(cpath, mode);
 #endif
-        string_cstring_free(cpath);
         if (error) {
             const char * const errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -220,9 +215,8 @@
 
     METHOD stat(STRING *path) {
         struct stat info;
-        char  * const cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
         const int     error = stat(cpath, &info);
-        string_cstring_free(cpath);
 
         if (error) {
             const char * const errmsg = strerror(errno);
@@ -280,13 +274,12 @@
     METHOD lstat(STRING *path) {
         struct stat info;
 
-        char * const cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
 #ifdef WIN32
         const int error = stat(cpath, &info);
 #else
         const int error = lstat(cpath, &info);
 #endif
-        string_cstring_free(cpath);
 
         if (error) {
             const char * const errmsg = strerror(errno);
@@ -327,13 +320,10 @@
 
     METHOD symlink(STRING *from, STRING *to) {
 #ifndef WIN32
-        char * const cfrom = string_to_cstring(interp, from);
-        char * const cto   = string_to_cstring(interp, to);
+        const char * const cfrom = Parrot_string_get_cstring(interp, from);
+        const char * const cto = Parrot_string_get_cstring(interp, to);
         const int error    = symlink(cfrom, cto);
 
-        string_cstring_free(cfrom);
-        string_cstring_free(cto);
-
         if (error) {
             const char * const errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -356,13 +346,10 @@
 
     METHOD link(STRING *from, STRING *to) {
 #ifndef WIN32
-        char * const cfrom = string_to_cstring(interp, from);
-        char * const cto   = string_to_cstring(interp, to);
+        const char * const cfrom = Parrot_string_get_cstring(interp, from);
+        const char * const cto = Parrot_string_get_cstring(interp, to);
         const int    error = link(cfrom, cto);
 
-        string_cstring_free(cfrom);
-        string_cstring_free(cto);
-
         if (error) {
             const char * const errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -410,11 +397,9 @@
 
     METHOD chroot(STRING *path) {
 #ifndef WIN32
-        char * const cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
         const int    error = chroot(cpath);
 
-        string_cstring_free(cpath);
-
         if (error) {
             const char * const errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -439,12 +424,10 @@
 #ifndef _MSC_VER
         struct dirent *dirent;
         PMC           *array;
-        char          *cpath = string_to_cstring(interp, path);
+        const char * const cpath = Parrot_string_get_cstring(interp, path);
         STRING        *retval;
         DIR           *dir   = opendir(cpath);
 
-        string_cstring_free(cpath);
-
         if (!dir) {
             const char * const errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -474,13 +457,10 @@
 =cut
 */
     METHOD rename(STRING *oldpath, STRING *newpath) {
-        char * const coldpath = string_to_cstring(interp, oldpath);
-        char * const cnewpath = string_to_cstring(interp, newpath);
-        const int    ret      = rename(coldpath, cnewpath);
+        const char * const cfrom = Parrot_string_get_cstring(interp, oldpath);
+        const char * const cto = Parrot_string_get_cstring(interp, newpath);
+        const int    ret      = rename(cfrom, cto);
 
-        string_cstring_free(coldpath);
-        string_cstring_free(cnewpath);
-
         if (ret < 0) {
             const char * const errmsg = strerror(errno) ;
             real_exception(interp, NULL, E_SystemError, "%s", errmsg);
Index: src/pmc/env.pmc
===================================================================
--- src/pmc/env.pmc	(revisión: 28225)
+++ src/pmc/env.pmc	(copia de trabajo)
@@ -154,14 +154,12 @@
             }
         }
         else {
-            char * const keyname = string_to_cstring(interp,
+            const char * const keyname = Parrot_string_get_cstring(interp,
                 VTABLE_get_string(interp, key));
-            char *val            = NULL;
 
             if (keyname) {
                 int free_it = 0;
-                val         = Parrot_getenv(keyname, &free_it);
-                string_cstring_free(keyname);
+                char * val  = Parrot_getenv(keyname, &free_it);
 
                 if (val) {
                     STRING *retval = string_from_cstring(interp, val, 0);
@@ -189,17 +187,15 @@
 */
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        char * const keyname = string_to_cstring(INTERP,
+        const char * const keyname = Parrot_string_get_cstring(INTERP,
             VTABLE_get_string(INTERP, key));
 
-        char   *val     = NULL;
         STRING *retval  = NULL;
         PMC    *return_pmc;
 
         if (keyname) {
             int free_it = 0;
-            val         = Parrot_getenv(keyname, &free_it);
-            string_cstring_free(keyname);
+            char * val = Parrot_getenv(keyname, &free_it);
 
             if (val) {
                 retval = string_from_cstring(INTERP, val, 0);
@@ -228,18 +224,12 @@
 */
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
-        char * const keyname = string_to_cstring(INTERP,
+        const char * const keyname = Parrot_string_get_cstring(INTERP,
             VTABLE_get_string(INTERP, key));
-        char * const env_val = string_to_cstring(INTERP, value);
+        const char * const env_val = Parrot_string_get_cstring(INTERP, value);
 
         if (keyname && env_val)
             Parrot_setenv(keyname, env_val);
-
-        if (keyname)
-            string_cstring_free(keyname);
-
-        if (env_val)
-            string_cstring_free(env_val);
     }
 
 /*
@@ -253,20 +243,13 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        char * const keyname = string_to_cstring(INTERP,
+        const char * const keyname = Parrot_string_get_cstring(INTERP,
             VTABLE_get_string(INTERP, key));
+        const char * const env_val = Parrot_string_get_cstring(INTERP,
+            VTABLE_get_string(INTERP, value));
 
-        const STRING * const str_value = VTABLE_get_string(INTERP, value);
-        char         * const env_val   = string_to_cstring(INTERP, str_value);
-
         if (keyname && env_val)
             Parrot_setenv(keyname, env_val);
-
-        if (keyname)
-            string_cstring_free(keyname);
-
-        if (env_val)
-            string_cstring_free(env_val);
     }
 
 /*
@@ -280,13 +263,12 @@
 */
 
     VTABLE INTVAL exists_keyed(PMC *key) {
-        char * const keyname = string_to_cstring(INTERP,
+        const char * const keyname = Parrot_string_get_cstring(INTERP,
             VTABLE_get_string(INTERP, key));
 
         if (keyname) {
             int free_it;
             char * const val = Parrot_getenv(keyname, &free_it);
-            string_cstring_free(keyname);
 
             if (val) {
                 if (free_it)
@@ -309,7 +291,7 @@
 */
 
     VTABLE void delete_keyed(PMC *key) {
-        char * const keyname = string_to_cstring(INTERP,
+        const char * const keyname = Parrot_string_get_cstring(INTERP,
             VTABLE_get_string(INTERP, key));
 
         if (keyname) {
@@ -322,8 +304,6 @@
 
                 Parrot_unsetenv(keyname);
             }
-
-            string_cstring_free(keyname);
         }
     }
 }
Index: src/pmc/file.pmc
===================================================================
--- src/pmc/file.pmc	(revisión: 28225)
+++ src/pmc/file.pmc	(copia de trabajo)
@@ -66,13 +66,12 @@
 
     METHOD exists(STRING *path) {
         struct stat info;
-        char *cpath = string_to_cstring(interp, path);
+        const char *cpath = Parrot_string_get_cstring(interp, path);
 #ifdef WIN32
         int error   = stat(cpath, &info);
 #else
         int error   = lstat(cpath, &info);
 #endif
-        string_cstring_free(cpath);
 
         if (error)
             RETURN(INTVAL 0);
@@ -92,13 +91,12 @@
 
     METHOD is_dir(STRING *path) {
         struct stat info;
-        char *cpath = string_to_cstring(interp, path);
+        const char *cpath = Parrot_string_get_cstring(interp, path);
 #ifdef WIN32
         int error   = stat(cpath, &info);
 #else
         int error   = lstat(cpath, &info);
 #endif
-        string_cstring_free(cpath);
 
         if (error) {
             char *errmsg = strerror(errno);
@@ -123,13 +121,12 @@
 
     METHOD is_file(STRING *path) {
         struct stat info;
-        char *cpath = string_to_cstring(interp, path);
+        const char *cpath = Parrot_string_get_cstring(interp, path);
 #ifdef WIN32
         int error   = stat(cpath, &info);
 #else
         int error   = lstat(cpath, &info);
 #endif
-        string_cstring_free(cpath);
 
         if (error) {
             char *errmsg = strerror(errno);
@@ -159,11 +156,9 @@
 #else
         struct stat info;
 
-        char *cpath = string_to_cstring(interp, path);
+        const char *cpath = Parrot_string_get_cstring(interp, path);
         int error   = lstat(cpath, &info);
 
-        string_cstring_free(cpath);
-
         if (error) {
             char *errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
@@ -195,17 +190,13 @@
     METHOD copy(STRING *from, STRING *to) {
 #define CHUNK_SIZE 1024
 
-        char *cfrom  = string_to_cstring(interp, from);
+        const char *cfrom  = Parrot_string_get_cstring(interp, from);
         FILE *source = fopen(cfrom, "rb");
 
-        string_cstring_free(cfrom);
-
         if (source) {
-            char *cto    = string_to_cstring(interp, to);
+            const char *cto    = Parrot_string_get_cstring(interp, to);
             FILE *target = fopen(cto, "w+b");
 
-            string_cstring_free(cto);
-
             if (target) {
                 char buf[CHUNK_SIZE];
                 int bytes_read, bytes_written;
@@ -247,13 +238,10 @@
 */
 
     METHOD rename(STRING *from, STRING *to) {
-        char *cfrom = string_to_cstring(interp, from);
-        char *cto   = string_to_cstring(interp, to);
+        const char *cfrom = Parrot_string_get_cstring(interp, from);
+        const char *cto   = Parrot_string_get_cstring(interp, to);
         int error   = rename(cfrom, cto);
 
-        string_cstring_free(cfrom);
-        string_cstring_free(cto);
-
         if (error) {
             char *errmsg = strerror(errno);
             real_exception(interp, NULL, E_SystemError, errmsg);
Index: src/datatypes.c
===================================================================
--- src/datatypes.c	(revisión: 28225)
+++ src/datatypes.c	(copia de trabajo)
@@ -40,18 +40,18 @@
 INTVAL
 Parrot_get_datatype_enum(PARROT_INTERP, ARGIN(const STRING *type_name))
 {
-    char * const type = string_to_cstring(interp, type_name);
+    const char * const type = Parrot_string_get_cstring(interp, type_name);
     int i;
 
+    if (! type)
+        return enum_type_undef;
+
     for (i = enum_first_type; i < enum_last_type; i++) {
         if (strcmp(data_types[i - enum_first_type].name, type) == 0) {
-            string_cstring_free(type);
             return i;
         }
     }
 
-    string_cstring_free(type);
-
     return enum_type_undef;
 }
 
Index: src/library.c
===================================================================
--- src/library.c	(revisión: 28225)
+++ src/library.c	(copia de trabajo)
@@ -514,7 +514,7 @@
         enum_runtime_ft type)
 {
     STRING *prefix;
-    STRING *full_name;
+    STRING *full_name = 0;
     PMC    *paths;
     INTVAL  i, n;
     char   *prefix_c;
Index: src/packfile.c
===================================================================
--- src/packfile.c	(revisión: 28225)
+++ src/packfile.c	(copia de trabajo)
@@ -2430,15 +2430,10 @@
                 PIO_printf(interp, "        MAPPINGTYPE => NONE\n");
                 break;
             case PF_DEBUGMAPPINGTYPE_FILENAME:
-                {
-                char *filename;
-
-                PIO_printf(interp, "        MAPPINGTYPE => FILENAME,\n");
-                filename = string_to_cstring(interp, PF_CONST(debug->code,
-                           debug->mappings[i]->u.filename)->u.string);
-                PIO_printf(interp, "        FILENAME => %s\n", filename);
-                string_cstring_free(filename);
-                }
+                PIO_printf(interp, "        MAPPINGTYPE => FILENAME,\n"
+                                   "        FILENAME => %Ss\n",
+                    PF_CONST(debug->code, debug->mappings[i]->u.filename)->
+                        u.string);
                 break;
             case PF_DEBUGMAPPINGTYPE_SOURCESEG:
                 PIO_printf(interp, "        MAPPINGTYPE => SOURCESEG,\n");
@@ -2894,7 +2889,8 @@
     }
 
     for (i = 0; i < self->fixup_count; i++) {
-        mem_sys_free(self->fixups[i]->name);
+        DECL_CONST_CAST;
+        mem_sys_free(PARROT_const_cast(char *, self->fixups[i]->name));
         self->fixups[i]->name = NULL;
         mem_sys_free(self->fixups[i]);
         self->fixups[i] = NULL;
@@ -3216,6 +3212,30 @@
     return found ? ep : NULL;
 }
 
+PARROT_API
+PARROT_WARN_UNUSED_RESULT
+int PackFile_find_fixup_entry_data(PARROT_INTERP,
+    INTVAL type,
+    ARGIN(const char *name),
+    ARGMOD(PackFile_FixupEntryData * data))
+{
+    /* TODO make a hash of all fixups */
+    PackFile_Directory * const dir = interp->code->base.dir;
+    PackFile_FixupEntry ep;
+    int found;
+
+    ep.type = type;
+    ep.name = name;
+    found    = PackFile_map_segments(interp, dir, find_fixup_iter, (void *) & ep);
+    if (found) {
+        data->offset= ep.offset;
+        data->seg= ep.seg;
+        return 1;
+    }
+    else
+        return 0;
+}
+
 /*
 
 =back
@@ -3730,7 +3750,7 @@
 void
 Parrot_load_bytecode(PARROT_INTERP, ARGIN(STRING *file_str))
 {
-    char *filename;
+    const char *filename;
     STRING *wo_ext, *ext, *pbc, *path;
     enum_runtime_ft file_type;
     PMC *is_loaded_hash;
@@ -3754,10 +3774,9 @@
     /* remember wo_ext => full_path mapping */
     VTABLE_set_string_keyed_str(interp, is_loaded_hash,
             wo_ext, path);
-    filename = string_to_cstring(interp, path);
+    filename = Parrot_string_get_cstring(interp, path);
     if (file_type == PARROT_RUNTIME_FT_PBC) {
         PackFile *pf = PackFile_append_pbc(interp, filename);
-        string_cstring_free(filename);
 
         if (!pf)
             real_exception(interp, NULL, 1,
@@ -3768,7 +3787,6 @@
         PackFile_ByteCode * const cs =
             (PackFile_ByteCode *)IMCC_compile_file_s(interp,
                 filename, &err);
-        string_cstring_free(filename);
 
         if (cs)
             do_sub_pragmas(interp, cs, PBC_LOADED, NULL);
Index: src/io/io_layers.c
===================================================================
--- src/io/io_layers.c	(revisión: 28225)
+++ src/io/io_layers.c	(copia de trabajo)
@@ -200,11 +200,11 @@
 void
 PIO_push_layer_str(PARROT_INTERP, ARGIN(PMC *pmc), ARGIN_NULLOK(const STRING *ls))
 {
-    char * const cls = string_to_cstring(interp, ls);
-    ParrotIOLayer * const l = PIO_get_layer(interp, cls);
+    const char * const cls = Parrot_string_get_cstring(interp, ls);
+    ParrotIOLayer * const l = cls ? PIO_get_layer(interp, cls) :
+        (ParrotIOLayer *) NULL;
     ParrotIOLayer * newlayer;
 
-    string_cstring_free(cls);
     if (!l)
         real_exception(interp, NULL, 1, "Layer not found");
 
Index: src/io/io_unix.c
===================================================================
--- src/io/io_unix.c	(revisión: 28225)
+++ src/io/io_unix.c	(copia de trabajo)
@@ -743,7 +743,7 @@
     /* Hard coded to IPv4 for now */
     const int family = AF_INET;
 
-    char * const s = string_to_cstring(interp, addr);
+    const char * const s = Parrot_string_get_cstring(interp, addr);
     /*
      * due to a bug in OS/X, we've to zero the struct
      * else bind is failing erratically
@@ -765,13 +765,11 @@
         struct hostent *he = gethostbyname(s);
         /* XXX FIXME - Handle error condition better */
         if (!he) {
-            string_cstring_free(s);
             fprintf(stderr, "gethostbyname failure [%s]\n", s);
             return NULL;
         }
         memcpy((char*)&sa.sin_addr, he->h_addr, sizeof (sa.sin_addr));
     }
-    string_cstring_free(s);
 
     sa.sin_family = family;
     sa.sin_port = htons(port);
Index: include/parrot/string_funcs.h
===================================================================
--- include/parrot/string_funcs.h	(revisión: 28225)
+++ include/parrot/string_funcs.h	(copia de trabajo)
@@ -53,6 +53,14 @@
         FUNC_MODIFIES(*d);
 
 PARROT_API
+void
+Parrot_string_free_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *str));
+
+PARROT_API
+const char *
+Parrot_string_get_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *str));
+
+PARROT_API
 PARROT_PURE_FUNCTION
 PARROT_CANNOT_RETURN_NULL
 const char * Parrot_string_cstring(SHIM_INTERP, ARGIN(const STRING *str))
Index: include/parrot/pobj.h
===================================================================
--- include/parrot/pobj.h	(revisión: 28225)
+++ include/parrot/pobj.h	(copia de trabajo)
@@ -121,6 +121,7 @@
     UnionVal    cache;
     Parrot_UInt flags;
     char       *strstart;
+    const char *cstring_val;
     UINTVAL     bufused;
     UINTVAL     strlen;
     UINTVAL     hashval; /* cached hash value computation */
Index: include/parrot/packfile.h
===================================================================
--- include/parrot/packfile.h	(revisión: 28225)
+++ include/parrot/packfile.h	(copia de trabajo)
@@ -154,11 +154,16 @@
 */
 typedef struct PackFile_FixupEntry {
     opcode_t                  type;     /* who knows what fixups we need? */
-    char                     *name;     /* name of the label */
+    const char               *name;     /* name of the label */
     opcode_t                  offset;   /* location of the item */
     struct PackFile_ByteCode *seg;
 } PackFile_FixupEntry;
 
+typedef struct PackFile_FixupEntryData {
+    opcode_t                  offset;   /* location of the item */
+    struct PackFile_ByteCode *seg;
+} PackFile_FixupEntryData;
+
 typedef enum {
     enum_fixup_none,
     enum_fixup_label,
@@ -432,6 +437,16 @@
 
 PARROT_API
 PARROT_WARN_UNUSED_RESULT
+int PackFile_find_fixup_entry_data(PARROT_INTERP,
+    INTVAL type,
+    ARGIN(const char *name),
+    ARGMOD(PackFile_FixupEntryData * data))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4);
+
+PARROT_API
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 PackFile_Segment * PackFile_find_segment(PARROT_INTERP,
     ARGIN_NULLOK(PackFile_Directory *dir),

Reply via email to