summaryrefslogtreecommitdiffstats
path: root/generic/tclListObj.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2017-09-12 17:01:55 (GMT)
committerdgp <dgp@users.sourceforge.net>2017-09-12 17:01:55 (GMT)
commit41765c8938c367e0824c280bbfe292bec64d52e1 (patch)
treeb79ed1fa176d3813e4b8db85ebbf42520079b635 /generic/tclListObj.c
parentde6b083f580fde9bac4b7498524a30b87581fabb (diff)
downloadtcl-41765c8938c367e0824c280bbfe292bec64d52e1.zip
tcl-41765c8938c367e0824c280bbfe292bec64d52e1.tar.gz
tcl-41765c8938c367e0824c280bbfe292bec64d52e1.tar.bz2
Rework [lset] internals to be sure outdated intreps get purged.
Diffstat (limited to 'generic/tclListObj.c')
-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;
}