Don't create uninitialized string objects from "" string literals.

This commit is contained in:
Bob Nystrom
2014-12-06 10:04:46 -08:00
parent e3cf80127b
commit da7aca5dd2
3 changed files with 28 additions and 10 deletions

View File

@ -957,7 +957,7 @@ DEF_NATIVE(string_subscript)
// The result is a one-character string.
// TODO: Handle UTF-8.
Value value = wrenNewString(vm, NULL, 2);
Value value = wrenNewUninitializedString(vm, 2);
ObjString* result = AS_STRING(value);
result->value[0] = AS_CSTRING(args[0])[index];
result->value[1] = '\0';

View File

@ -322,6 +322,23 @@ Value wrenNewRange(WrenVM* vm, double from, double to, bool isInclusive)
}
Value wrenNewString(WrenVM* vm, const char* text, size_t length)
{
// Allow NULL if the string is empty since byte buffers don't allocate any
// characters for a zero-length string.
ASSERT(length == 0 || text != NULL, "Unexpected NULL string.");
// TODO: Don't allocate a heap string at all for zero-length strings.
ObjString* string = AS_STRING(wrenNewUninitializedString(vm, length));
// Copy the string (if given one).
if (length > 0) strncpy(string->value, text, length);
string->value[length] = '\0';
return OBJ_VAL(string);
}
Value wrenNewUninitializedString(WrenVM* vm, size_t length)
{
// Allocate before the string object in case this triggers a GC which would
// free the string object.
@ -331,13 +348,6 @@ Value wrenNewString(WrenVM* vm, const char* text, size_t length)
initObj(vm, &string->obj, OBJ_STRING);
string->value = heapText;
// Copy the string (if given one).
if (text != NULL)
{
strncpy(heapText, text, length);
heapText[length] = '\0';
}
return OBJ_VAL(string);
}
@ -346,7 +356,7 @@ ObjString* wrenStringConcat(WrenVM* vm, const char* left, const char* right)
size_t leftLength = strlen(left);
size_t rightLength = strlen(right);
Value value = wrenNewString(vm, NULL, leftLength + rightLength);
Value value = wrenNewUninitializedString(vm, leftLength + rightLength);
ObjString* string = AS_STRING(value);
strcpy(string->value, left);
strcpy(string->value + leftLength, right);

View File

@ -588,9 +588,17 @@ Value wrenListRemoveAt(WrenVM* vm, ObjList* list, int index);
// Creates a new range from [from] to [to].
Value wrenNewRange(WrenVM* vm, double from, double to, bool isInclusive);
// Creates a new string object and copies [text] into it.
// Creates a new string object of [length] and copies [text] into it.
//
// [text] may be NULL if [length] is zero.
Value wrenNewString(WrenVM* vm, const char* text, size_t length);
// Creates a new string object with a buffer large enough to hold a string of
// [length] but does no initialization of the buffer.
//
// The caller is expected to fully initialize the buffer after calling.
Value wrenNewUninitializedString(WrenVM* vm, size_t length);
// Creates a new string that is the concatenation of [left] and [right].
ObjString* wrenStringConcat(WrenVM* vm, const char* left, const char* right);