summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2022-11-05 11:49:08 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2022-11-05 11:49:08 (GMT)
commitc3c5a80a02a02427696394cb0ed1f8adeab1099d (patch)
tree2a821319db65ee920a8d0fb027a68ddcb51c903d /generic/tclExecute.c
parent6559f4084e844e187198c5471bfd15f19c8dfecc (diff)
parentd9033672db616bb406894a480e90410666ff4545 (diff)
downloadtcl-c3c5a80a02a02427696394cb0ed1f8adeab1099d.zip
tcl-c3c5a80a02a02427696394cb0ed1f8adeab1099d.tar.gz
tcl-c3c5a80a02a02427696394cb0ed1f8adeab1099d.tar.bz2
Merge 8.7. lreplace4 bcc instruction and FLT_MAX fix
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c103
1 files changed, 98 insertions, 5 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 444f9aa..e2a2705 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -5034,11 +5034,104 @@ TEBCresume(
NEXT_INST_F(1, 1, 0);
}
- /*
- * End of INST_LIST and related instructions.
- * -----------------------------------------------------------------
- * Start of string-related instructions.
- */
+ case INST_LREPLACE4:
+ {
+ Tcl_Size numToDelete, numNewElems;
+ int end_indicator;
+ int haveSecondIndex, flags;
+ Tcl_Obj *fromIdxObj, *toIdxObj;
+ opnd = TclGetInt4AtPtr(pc + 1);
+ flags = TclGetInt1AtPtr(pc + 5);
+
+ /* Stack: ... listobj index1 ?index2? new1 ... newN */
+ valuePtr = OBJ_AT_DEPTH(opnd-1);
+
+ /* haveSecondIndex==0 => pure insert */
+ haveSecondIndex = (flags & TCL_LREPLACE4_SINGLE_INDEX) == 0;
+ numNewElems = opnd - 2 - haveSecondIndex;
+
+ /* end_indicator==1 => "end" is last element's index, 0=>index beyond */
+ end_indicator = (flags & TCL_LREPLACE4_END_IS_LAST) != 0;
+ fromIdxObj = OBJ_AT_DEPTH(opnd - 2);
+ toIdxObj = haveSecondIndex ? OBJ_AT_DEPTH(opnd - 3) : NULL;
+ if (Tcl_ListObjLength(interp, valuePtr, &length) != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+
+ DECACHE_STACK_INFO();
+
+ if (TclGetIntForIndexM(
+ interp, fromIdxObj, length - end_indicator, &fromIdx)
+ != TCL_OK) {
+ CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ if (fromIdx == TCL_INDEX_NONE) {
+ fromIdx = 0;
+ }
+ else if (fromIdx > length) {
+ fromIdx = length;
+ }
+ numToDelete = 0;
+ if (toIdxObj) {
+ if (TclGetIntForIndexM(
+ interp, toIdxObj, length - end_indicator, &toIdx)
+ != TCL_OK) {
+ CACHE_STACK_INFO();
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ if (toIdx != TCL_INDEX_NONE) {
+ if (toIdx > length) {
+ toIdx = length;
+ }
+ if (toIdx >= fromIdx) {
+ numToDelete = toIdx - fromIdx + 1;
+ }
+ }
+ }
+
+ CACHE_STACK_INFO();
+
+ if (Tcl_IsShared(valuePtr)) {
+ objResultPtr = Tcl_DuplicateObj(valuePtr);
+ if (Tcl_ListObjReplace(interp,
+ objResultPtr,
+ fromIdx,
+ numToDelete,
+ numNewElems,
+ &OBJ_AT_DEPTH(numNewElems - 1))
+ != TCL_OK) {
+ TRACE_ERROR(interp);
+ Tcl_DecrRefCount(objResultPtr);
+ goto gotError;
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ NEXT_INST_V(6, opnd, 1);
+ }
+ else {
+ if (Tcl_ListObjReplace(interp,
+ valuePtr,
+ fromIdx,
+ numToDelete,
+ numNewElems,
+ &OBJ_AT_DEPTH(numNewElems - 1))
+ != TCL_OK) {
+ TRACE_ERROR(interp);
+ goto gotError;
+ }
+ TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+ NEXT_INST_V(6, opnd - 1, 0);
+ }
+ }
+
+ /*
+ * End of INST_LIST and related instructions.
+ * -----------------------------------------------------------------
+ * Start of string-related instructions.
+ */
case INST_STR_EQ:
case INST_STR_NEQ: /* String (in)equality check */