summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 6b850e3..2cf8b4a 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -379,6 +379,7 @@ Tcl_NewUnicodeObj(
Tcl_Obj *objPtr;
TclNewObj(objPtr);
+ TclStringSetPrev(objPtr, NULL);
SetUnicodeObj(objPtr, unicode, numChars);
return objPtr;
}
@@ -987,11 +988,17 @@ Tcl_SetUnicodeObj(
int numChars) /* Number of characters in the unicode
* string. */
{
+ Tcl_Obj *prevPtr = NULL;
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_SetUnicodeObj");
}
+ if (objPtr->typePtr != NULL && objPtr->typePtr != &tclStringType) {
+ prevPtr = Tcl_DuplicateObj(objPtr);
+ Tcl_IncrRefCount(prevPtr);
+ }
TclFreeIntRep(objPtr);
SetUnicodeObj(objPtr, unicode, numChars);
+ TclStringSetPrev(objPtr, prevPtr);
}
static int
@@ -1037,7 +1044,6 @@ SetUnicodeObj(
stringPtr->unicode[numChars] = 0;
stringPtr->numChars = numChars;
stringPtr->hasUnicode = 1;
-
TclInvalidateStringRep(objPtr);
stringPtr->allocated = 0;
}
@@ -1373,6 +1379,9 @@ AppendUnicodeToUnicodeRep(
}
SetStringFromAny(NULL, objPtr);
+ if (appendNumChars > 0) {
+ TclStringInvalidatePrev(objPtr);
+ }
stringPtr = GET_STRING(objPtr);
/*
@@ -1526,6 +1535,7 @@ AppendUtfToUtfRep(
if (numBytes == 0) {
return;
}
+ TclStringInvalidatePrev(objPtr);
/*
* Copy the new string onto the end of the old string, then add the
@@ -2827,6 +2837,9 @@ ExtendUnicodeRepWithString(
if (numAppendChars == -1) {
TclNumUtfChars(numAppendChars, bytes, numBytes);
}
+ if (numAppendChars > 0) {
+ TclStringInvalidatePrev(objPtr);
+ }
needed = numOrigChars + numAppendChars;
stringCheckLimits(needed);
@@ -2874,6 +2887,7 @@ DupStringInternalRep(
{
String *srcStringPtr = GET_STRING(srcPtr);
String *copyStringPtr = NULL;
+ Tcl_Obj *prevPtr;
if (srcStringPtr->numChars == -1) {
/*
@@ -2915,10 +2929,15 @@ DupStringInternalRep(
* code, so it doesn't contain any extra bytes that might exist in the
* source object.
*/
-
copyStringPtr->allocated = copyPtr->bytes ? copyPtr->length : 0;
SET_STRING(copyPtr, copyStringPtr);
+ prevPtr = TclStringGetPrev(srcPtr);
+ if (prevPtr != NULL) {
+ prevPtr = Tcl_DuplicateObj(prevPtr);
+ Tcl_IncrRefCount(prevPtr);
+ }
+ TclStringSetPrev(copyPtr, prevPtr);
copyPtr->typePtr = &tclStringType;
}
@@ -2946,6 +2965,8 @@ SetStringFromAny(
{
if (objPtr->typePtr != &tclStringType) {
String *stringPtr = stringAlloc(0);
+ Tcl_Obj *prevPtr = Tcl_DuplicateObj(objPtr);
+ Tcl_IncrRefCount(prevPtr);
/*
* Convert whatever we have into an untyped value. Just A String.
@@ -2964,6 +2985,7 @@ SetStringFromAny(
stringPtr->maxChars = 0;
stringPtr->hasUnicode = 0;
SET_STRING(objPtr, stringPtr);
+ TclStringSetPrev(objPtr, prevPtr);
objPtr->typePtr = &tclStringType;
}
return TCL_OK;
@@ -3022,6 +3044,7 @@ ExtendStringRepWithUnicode(
if (numChars == 0) {
return 0;
}
+ TclStringInvalidatePrev(objPtr);
if (objPtr->bytes == NULL) {
objPtr->length = 0;
@@ -3083,10 +3106,23 @@ static void
FreeStringInternalRep(
Tcl_Obj *objPtr) /* Object with internal rep to free. */
{
+ Tcl_Obj * prevPtr = TclStringGetPrev(objPtr);
+ if (prevPtr != NULL) {
+ Tcl_DecrRefCount(prevPtr);
+ }
ckfree(GET_STRING(objPtr));
objPtr->typePtr = NULL;
}
+static void InvalidateCachedReps(
+ Tcl_Obj *objPtr
+) {
+ Tcl_Obj * prevPtr = TclStringGetPrev(objPtr);
+ if (prevPtr != NULL) {
+ Tcl_DecrRefCount(TclStringGetPrev(objPtr));
+ }
+}
+
/*
* Local Variables:
* mode: c