summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2017-09-12 17:01:00 (GMT)
committerdgp <dgp@users.sourceforge.net>2017-09-12 17:01:00 (GMT)
commite899145b8bcf33f031f325cf2595d0df9d42ceb7 (patch)
treefcebbccbcaef5890492f5a12b61589096d12e555 /generic
parentae3f6c9d002aec97ad7abcc5a13a4a2b0b31620c (diff)
downloadtcl-e899145b8bcf33f031f325cf2595d0df9d42ceb7.zip
tcl-e899145b8bcf33f031f325cf2595d0df9d42ceb7.tar.gz
tcl-e899145b8bcf33f031f325cf2595d0df9d42ceb7.tar.bz2
Rework [lset] internals to be sure outdated intreps get purged.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclListObj.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index f60329d..c6d8d0e 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -1594,23 +1594,32 @@ TclLsetFlat(
while (chainPtr) {
Tcl_Obj *objPtr = chainPtr;
+ List *listRepPtr;
+ /*
+ * Clear away our intrep surgery mess.
+ */
+
+ irPtr = Tcl_FetchIntRep(objPtr, &tclListType);
+ listRepPtr = irPtr->twoPtrValue.ptr1;
+ chainPtr = irPtr->twoPtrValue.ptr2;
+
if (result == TCL_OK) {
+
/*
* We're going to store valuePtr, so spoil string reps of all
* containing lists.
*/
+ listRepPtr->refCount++;
+ TclFreeIntRep(objPtr);
+ ListSetIntRep(objPtr, listRepPtr);
+ listRepPtr->refCount--;
+
TclInvalidateStringRep(objPtr);
+ } else {
+ irPtr->twoPtrValue.ptr2 = NULL;
}
-
- /*
- * Clear away our intrep surgery mess.
- */
-
- irPtr = Tcl_FetchIntRep(objPtr, &tclListType);
- chainPtr = irPtr->twoPtrValue.ptr2;
- irPtr->twoPtrValue.ptr2 = NULL;
}
if (result != TCL_OK) {
@@ -1637,8 +1646,8 @@ TclLsetFlat(
Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr);
} else {
TclListObjSetElement(NULL, subListPtr, index, valuePtr);
+ TclInvalidateStringRep(subListPtr);
}
- TclInvalidateStringRep(subListPtr);
Tcl_IncrRefCount(retValuePtr);
return retValuePtr;
}
@@ -1781,6 +1790,18 @@ TclListObjSetElement(
elemPtrs[index] = valuePtr;
+ /*
+ * Invalidate outdated intreps.
+ */
+
+ ListGetIntRep(listPtr, listRepPtr);
+ listRepPtr->refCount++;
+ TclFreeIntRep(listPtr);
+ ListSetIntRep(listPtr, listRepPtr);
+ listRepPtr->refCount--;
+
+ TclInvalidateStringRep(listPtr);
+
return TCL_OK;
}