summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpooryorick <com.digitalsmarties@pooryorick.com>2023-05-08 14:08:44 (GMT)
committerpooryorick <com.digitalsmarties@pooryorick.com>2023-05-08 14:08:44 (GMT)
commit8d076e6525835064d971940356ce83f9d7bd3d55 (patch)
tree5b613e845b24da679361c9ed55357e2cd41bd9aa
parentaf5bfc68cc1b458f1965b957bae448035b4c09a1 (diff)
downloadtcl-8d076e6525835064d971940356ce83f9d7bd3d55.zip
tcl-8d076e6525835064d971940356ce83f9d7bd3d55.tar.gz
tcl-8d076e6525835064d971940356ce83f9d7bd3d55.tar.bz2
Make TclLindexFlat() a litle more straightforward.
-rw-r--r--generic/tclListObj.c55
-rw-r--r--generic/tclUtil.c4
2 files changed, 36 insertions, 23 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index 6cc933c..170dd69 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -2656,6 +2656,7 @@ TclLindexFlat(
Tcl_Obj *const indexArray[])/* Array of pointers to Tcl objects that
* represent the indices in the list. */
{
+ int status;
Tcl_Size i;
/* Handle ArithSeries as special case */
@@ -2684,24 +2685,13 @@ TclLindexFlat(
for (i=0 ; i<indexCount && listObj ; i++) {
Tcl_Size index, listLen = 0;
- Tcl_Obj **elemPtrs = NULL, *sublistCopy;
+ Tcl_Obj **elemPtrs = NULL;
- /*
- * Here we make a private copy of the current sublist, so we avoid any
- * shimmering issues that might invalidate the elemPtr array below
- * while we are still using it. See test lindex-8.4.
- */
-
- sublistCopy = TclListObjCopy(interp, listObj);
- Tcl_DecrRefCount(listObj);
- listObj = NULL;
-
- if (sublistCopy == NULL) {
- /* The sublist is not a list at all => error. */
- break;
+ status = Tcl_ListObjLength(interp, listObj, &listLen);
+ if (status != TCL_OK) {
+ Tcl_DecrRefCount(listObj);
+ return NULL;
}
- LIST_ASSERT_TYPE(sublistCopy);
- ListObjGetElements(sublistCopy, listLen, elemPtrs);
if (TclGetIntForIndexM(interp, indexArray[i], /*endValue*/ listLen-1,
&index) == TCL_OK) {
@@ -2715,20 +2705,43 @@ TclLindexFlat(
if (TclGetIntForIndexM(
interp, indexArray[i], TCL_SIZE_MAX - 1, &index)
!= TCL_OK) {
- Tcl_DecrRefCount(sublistCopy);
+ Tcl_DecrRefCount(listObj);
return NULL;
}
}
+ Tcl_DecrRefCount(listObj);
TclNewObj(listObj);
+ Tcl_IncrRefCount(listObj);
} else {
+ Tcl_Obj *itemObj;
+ /*
+ * Must set the internal rep again because it may have been
+ * changed by TclGetIntForIndexM. See test lindex-8.4.
+ */
+ if (!TclHasInternalRep(listObj, &tclListType.objType)) {
+ status = SetListFromAny(interp, listObj);
+ if (status != TCL_OK) {
+ /* The list is not a list at all => error. */
+ Tcl_DecrRefCount(listObj);
+ return NULL;
+ }
+ }
+
+ ListObjGetElements(listObj, listLen, elemPtrs);
+ /* increment this reference count first before decrementing
+ * just in case they are the same Tcl_Obj
+ */
+ itemObj = elemPtrs[index];
+ Tcl_IncrRefCount(itemObj);
+ Tcl_DecrRefCount(listObj);
/* Extract the pointer to the appropriate element. */
- listObj = elemPtrs[index];
+ listObj = itemObj;
}
- Tcl_IncrRefCount(listObj);
+ } else {
+ Tcl_DecrRefCount(listObj);
+ listObj = NULL;
}
- Tcl_DecrRefCount(sublistCopy);
}
-
return listObj;
}
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index a5c1595..6112869 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -3799,8 +3799,8 @@ TclIndexEncode(
}
/*
* We passed 2*INT_MAX as the "end value" to GetWideForIndex. The computed
- * index will in one of the following ranges that need to be distinguished
- * for encoding purposes in the following code.
+ * index will be in one of the following ranges that need to be
+ * distinguished for encoding purposes in the following code.
* (1) 0:INT_MAX when
* (a) objPtr was a pure non-negative numeric value in that range
* (b) objPtr was a numeric computation M+/-N with a result in that range