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 */