diff --git a/runtime.c b/runtime.c index 712a9d83..f8dc57c0 100644 --- a/runtime.c +++ b/runtime.c @@ -2673,7 +2673,6 @@ object Cyc_string2utf8(void *data, object cont, object str, object start, { int s, e; int len; - make_empty_bytevector(result); Cyc_check_str(data, str); Cyc_check_num(data, start); @@ -2692,12 +2691,31 @@ object Cyc_string2utf8(void *data, object cont, object str, object start, } // Fast path - if (string_num_cp(str) == string_len(str)) { // TODO: disable for testing purposes - result.len = len; - result.data = alloca(sizeof(char) * len); - memcpy(&result.data[0], &(string_str(str))[s], len); - _return_closcall1(data, cont, &result); + if (string_num_cp(str) == string_len(str)) { + if (len >= MAX_STACK_OBJ) { + int heap_grown; + object bv = gc_alloc(((gc_thread_data *)data)->heap, + sizeof(bytevector_type) + len, + boolean_f, // OK to populate manually over here + (gc_thread_data *)data, + &heap_grown); + ((bytevector) bv)->hdr.mark = ((gc_thread_data *)data)->gc_alloc_color; + ((bytevector) bv)->hdr.grayed = 0; + ((bytevector) bv)->tag = bytevector_tag; + ((bytevector) bv)->len = len; + ((bytevector) bv)->data = (char *)(((char *)bv) + sizeof(bytevector_type)); + memcpy(&(((bytevector) bv)->data[0]), &(string_str(str))[s], len); + _return_closcall1(data, cont, bv); + } else { + make_empty_bytevector(result); + result.len = len; + result.data = alloca(sizeof(char) * len); + memcpy(&result.data[0], &(string_str(str))[s], len); + _return_closcall1(data, cont, &result); + } } else { +// TODO: if len > MAX_STACK_OBJ + make_empty_bytevector(result); const char *tmp = string_str(str); char_type codepoint; uint32_t state = 0;