Sorry, forgot to attach the file.

-- 
Salu2
Index: src/pdb.c
===================================================================
--- src/pdb.c	(revisión: 28197)
+++ 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->exceptions->msg));
         return;
     }
 
Index: src/oo.c
===================================================================
--- src/oo.c	(revisión: 28197)
+++ 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: 28197)
+++ 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/core.ops
===================================================================
--- src/ops/core.ops	(revisión: 28197)
+++ src/ops/core.ops	(copia de trabajo)
@@ -185,12 +185,11 @@
 =cut
 
 inline op branch_cs(in STR) :base_loop :check_event :flow {
-    char * const         label = string_to_cstring(interp, $1);
+    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);
         real_exception(interp, NULL, 1, "branch_cs: fixup for '%Ss' not found",
             $1);
     }
@@ -199,7 +198,6 @@
         Parrot_switch_to_cs(interp, fe->seg, 1);
     }
     mem_sys_free(fe);
-    string_cstring_free(label);
     interp->resume_flag = 2;
     goto ADDRESS(0);
 }
@@ -1244,7 +1242,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 +1262,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/global.c
===================================================================
--- src/global.c	(revisión: 28197)
+++ 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: 28197)
+++ 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: 28197)
+++ 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: 28197)
+++ 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: 28197)
+++ 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);
     }
 
 /*
Index: src/pmc/file.pmc
===================================================================
--- src/pmc/file.pmc	(revisión: 28197)
+++ 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: 28197)
+++ 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: 28197)
+++ 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/io/io_layers.c
===================================================================
--- src/io/io_layers.c	(revisión: 28197)
+++ 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: include/parrot/string_funcs.h
===================================================================
--- include/parrot/string_funcs.h	(revisión: 28197)
+++ 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: 28197)
+++ 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 */

Reply via email to