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),