diff options
| author | pooryorick <com.digitalsmarties@pooryorick.com> | 2023-05-08 14:08:44 (GMT) |
|---|---|---|
| committer | pooryorick <com.digitalsmarties@pooryorick.com> | 2023-05-08 14:08:44 (GMT) |
| commit | 8d076e6525835064d971940356ce83f9d7bd3d55 (patch) | |
| tree | 5b613e845b24da679361c9ed55357e2cd41bd9aa | |
| parent | af5bfc68cc1b458f1965b957bae448035b4c09a1 (diff) | |
| download | tcl-8d076e6525835064d971940356ce83f9d7bd3d55.zip tcl-8d076e6525835064d971940356ce83f9d7bd3d55.tar.gz tcl-8d076e6525835064d971940356ce83f9d7bd3d55.tar.bz2 | |
Make TclLindexFlat() a litle more straightforward.
| -rw-r--r-- | generic/tclListObj.c | 55 | ||||
| -rw-r--r-- | generic/tclUtil.c | 4 |
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 |
