diff --git a/core/strings/strings-tests.factor b/core/strings/strings-tests.factor index 5ab7f1dffe..459ec7b153 100755 --- a/core/strings/strings-tests.factor +++ b/core/strings/strings-tests.factor @@ -51,6 +51,9 @@ unit-test [ "ab" ] [ 2 "abc" resize-string ] unit-test [ "abc\0\0\0" ] [ 6 "abc" resize-string ] unit-test +[ "\u001234b" ] [ 2 "\u001234bc" resize-string ] unit-test +[ "\u001234bc\0\0\0" ] [ 6 "\u001234bc" resize-string ] unit-test + ! Random tester found this [ { "kernel-error" 3 12 -7 } ] [ [ 2 -7 resize-string ] catch ] unit-test @@ -88,3 +91,5 @@ unit-test "\udeadbe" clone CHAR: \u123456 over clone set-first ] unit-test + + diff --git a/vm/data_gc.c b/vm/data_gc.c index 3ca41d602c..601a677920 100755 --- a/vm/data_gc.c +++ b/vm/data_gc.c @@ -505,7 +505,6 @@ CELL binary_payload_start(CELL pointer) switch(untag_header(get(pointer))) { /* these objects do not refer to other objects at all */ - case STRING_TYPE: case FLOAT_TYPE: case BYTE_ARRAY_TYPE: case BIT_ARRAY_TYPE: @@ -522,6 +521,8 @@ CELL binary_payload_start(CELL pointer) return CELLS * 2; case QUOTATION_TYPE: return sizeof(F_QUOTATION) - CELLS * 2; + case STRING_TYPE: + return sizeof(F_STRING); /* everything else consists entirely of pointers */ default: return unaligned_object_size(pointer); diff --git a/vm/types.c b/vm/types.c index 1f0287b1f0..24b5e7ff07 100755 --- a/vm/types.c +++ b/vm/types.c @@ -480,7 +480,16 @@ F_STRING* allot_string_internal(CELL capacity) void fill_string(F_STRING *string, CELL start, CELL capacity, CELL fill) { if(fill == 0) - memset((void*)SREF(string,start),'\0',capacity - start); + { + memset((void *)SREF(string,start),'\0',capacity - start); + + if(string->aux != F) + { + F_BYTE_ARRAY *aux = untag_object(string->aux); + memset((void *)BREF(aux,start * sizeof(u16)),'\0', + (capacity - start) * sizeof(u16)); + } + } else { CELL i; @@ -523,6 +532,19 @@ F_STRING* reallot_string(F_STRING* string, CELL capacity, CELL fill) memcpy(new_string + 1,string + 1,to_copy); + if(string->aux != F) + { + REGISTER_UNTAGGED(string); + REGISTER_UNTAGGED(new_string); + F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16)); + new_string->aux = tag_object(new_aux); + UNREGISTER_UNTAGGED(new_string); + UNREGISTER_UNTAGGED(string); + + F_BYTE_ARRAY *aux = untag_object(string->aux); + memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16)); + } + REGISTER_UNTAGGED(string); fill_string(new_string,to_copy,capacity,fill); UNREGISTER_UNTAGGED(string); @@ -573,7 +595,7 @@ DEFINE_PRIMITIVE(resize_string) MEMORY_TO_STRING(char,u8) MEMORY_TO_STRING(u16,u16) -// MEMORY_TO_STRING(u32,u32) +MEMORY_TO_STRING(u32,u32) bool check_string(F_STRING *s, CELL max) { diff --git a/vm/types.h b/vm/types.h index 6f4234af34..e5003ea069 100755 --- a/vm/types.h +++ b/vm/types.h @@ -83,8 +83,8 @@ INLINE CELL array_capacity(F_ARRAY* array) return array->capacity >> TAG_BITS; } -#define BREF(byte_array,index) ((CELL)byte_array + sizeof(F_BYTE_ARRAY) + index) -#define SREF(string,index) ((CELL)string + sizeof(F_STRING) + index) +#define BREF(byte_array,index) ((CELL)byte_array + sizeof(F_BYTE_ARRAY) + (index)) +#define SREF(string,index) ((CELL)string + sizeof(F_STRING) + (index)) INLINE F_STRING* untag_string(CELL tagged) {