Changes On Branch 771e5ad4e4ae8e03
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch bug-bc7ddc7944 Excluding Merge-Ins

This is equivalent to a diff from 55602e8331 to 771e5ad4e4

2024-08-20
12:50
Merge [55602e8331f44cf5], "Bug [bc076f4f0e]. Fix large indexing broken by commit [0b05b5c750df]. Als... check-in: 1083a2733e user: pooryorick tags: unchained, INCOMPATIBLE_LICENSE
2023-08-14
15:46
merge bug-bc7ddc7944 (revert use of TclDuplicatePureObj) check-in: 35275c285b user: griffin tags: trunk, main
12:55
Bug [457523]. Trivial comment edit just to close the bug check-in: bae0d30c7f user: apnadkarni tags: trunk, main
05:07
merge trunk Closed-Leaf check-in: 771e5ad4e4 user: griffin tags: bug-bc7ddc7944
03:42
Bug [bc076f4f0e]. Fix large indexing broken by commit [0b05b5c750df]. Also preserves Tk bug fix [a99... check-in: 55602e8331 user: apnadkarni tags: trunk, main
2023-08-13
13:37
Fix up tests for modified Tcl_GetIntForIndex semantics Closed-Leaf check-in: 06da22c87b user: apnadkarni tags: bug-bc076f4f0e75
04:29
merge trunk check-in: 7fc4b49ef9 user: griffin tags: bug-bc7ddc7944
2023-08-12
23:14
Rename Tcl_BumpObj() to Tcl_BounceRefCount(). After the presentation on Abstract Lists at the 2023 ... check-in: df58824c78 user: griffin tags: trunk, main

Changes to generic/tclArithSeries.c.
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1161







-
+







	int test = 0;

	incr = 0; // Check index+incr where incr is 0 and 1
        status = Tcl_GetDoubleFromObj(interp, valueObj, &y);
        if (status != TCL_OK) {
	    test = 0;
        } else {
            char *vstr = Tcl_GetStringFromObj(valueObj, &vlen);
            const char *vstr = Tcl_GetStringFromObj(valueObj, &vlen);
            index = (y - dblRepPtr->start) / dblRepPtr->step;
	    while (incr<2) {
		Tcl_Obj *elemObj;
		elen = 0;
		TclArithSeriesObjIndex(interp, arithSeriesObjPtr, (index+incr), &elemObj);
		const char *estr = elemObj ? Tcl_GetStringFromObj(elemObj, &elen) : "";
		/* "in" operation defined as a string compare */
Changes to generic/tclBasic.c.
6149
6150
6151
6152
6153
6154
6155
6156

6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6149
6150
6151
6152
6153
6154
6155

6156




6157
6158
6159
6160
6161
6162
6163







-
+
-
-
-
-







	 * both listPtr and objPtr.
	 *
	 * TODO: Create a test to demo this need, or eliminate it.
	 * FIXME OPT: preserve just the internal rep?
	 */

	Tcl_IncrRefCount(objPtr);
	listPtr = TclDuplicatePureObj(interp, objPtr, &tclListType);
	listPtr = TclListObjCopy(interp, objPtr);
	if (!listPtr) {
	    Tcl_DecrRefCount(objPtr);
	    return TCL_ERROR;
	}
	Tcl_IncrRefCount(listPtr);

	if (word != INT_MIN) {
	    /*
	     * TIP #280 Structures for tracking lines. As we know that this is
	     * dynamic execution we ignore the invoker, even if known.
	     *
Changes to generic/tclCmdAH.c.
2783
2784
2785
2786
2787
2788
2789
2790
2791


2792
2793
2794
2795
2796
2797
2798
2783
2784
2785
2786
2787
2788
2789


2790
2791
2792
2793
2794
2795
2796
2797
2798







-
-
+
+







    /*
     * Break up the value lists and variable lists into elements.
     */

    for (i=0 ; i<numLists ; i++) {
	/* List */
	/* Variables */
	statePtr->vCopyList[i] = Tcl_DuplicateObj(objv[1+i*2]);
	if (!statePtr->vCopyList[i]) {
	statePtr->vCopyList[i] = TclListObjCopy(interp, objv[1+i*2]);
	if (statePtr->vCopyList[i] == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}
	result = TclListObjLengthM(interp, statePtr->vCopyList[i],
	    &statePtr->varcList[i]);
	if (result != TCL_OK) {
	    result = TCL_ERROR;
2818
2819
2820
2821
2822
2823
2824

2825

2826
2827

2828
2829
2830
2831
2832
2833
2834
2818
2819
2820
2821
2822
2823
2824
2825

2826


2827
2828
2829
2830
2831
2832
2833
2834







+
-
+
-
-
+







	    if (statePtr->aCopyList[i] == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    /* Don't compute values here, wait until the last moment */
	    statePtr->argcList[i] = TclObjTypeLength(statePtr->aCopyList[i]);
	} else {
	    /* List values */
	    statePtr->aCopyList[i] = TclDuplicatePureObj(
	    statePtr->aCopyList[i] = TclListObjCopy(interp, objv[2+i*2]);
		interp, objv[2+i*2], &tclListType);
	    if (!statePtr->aCopyList[i]) {
	    if (statePtr->aCopyList[i] == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    result = TclListObjGetElementsM(interp, statePtr->aCopyList[i],
		&statePtr->argcList[i], &statePtr->argvList[i]);
	    if (result != TCL_OK) {
		goto done;
Changes to generic/tclCmdIL.c.
2311
2312
2313
2314
2315
2316
2317
2318
2319


2320
2321
2322
2323
2324
2325
2326
2311
2312
2313
2314
2315
2316
2317


2318
2319
2320
2321
2322
2323
2324
2325
2326







-
-
+
+







    int code;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "list ?varName ...?");
	return TCL_ERROR;
    }

    listCopyPtr = TclDuplicatePureObj(interp, objv[1], &tclListType);
    if (!listCopyPtr) {
    listCopyPtr = TclListObjCopy(interp, objv[1]);
    if (listCopyPtr == NULL) {
	return TCL_ERROR;
    }
    Tcl_IncrRefCount(listCopyPtr); /* Important! fs */

    code = TclListObjGetElementsM(
	interp, listCopyPtr, &listObjc, &listObjv);
    if (code != TCL_OK) {
2481
2482
2483
2484
2485
2486
2487
2488

2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2481
2482
2483
2484
2485
2486
2487

2488



2489
2490
2491
2492
2493
2494
2495







-
+
-
-
-







    /*
     * If the list object is unshared we can modify it directly. Otherwise we
     * create a copy to modify: this is "copy on write".
     */

    listPtr = objv[1];
    if (Tcl_IsShared(listPtr)) {
	listPtr = TclDuplicatePureObj(interp, listPtr, &tclListType);
	listPtr = TclListObjCopy(NULL, listPtr);
	if (!listPtr) {
	    return TCL_ERROR;
	}
	copied = 1;
    }

    if ((objc == 4) && (index == len)) {
	/*
	 * Special case: insert one element at the end of the list.
	 */
2686
2687
2688
2689
2690
2691
2692
2693

2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2683
2684
2685
2686
2687
2688
2689

2690



2691
2692
2693
2694
2695
2696
2697







-
+
-
-
-







    /*
     * Second, remove the element.
     * TclLsetFlat adds a ref count which is handled.
     */

    if (objc == 2) {
	if (Tcl_IsShared(listPtr)) {
	    listPtr = TclDuplicatePureObj(interp, listPtr, &tclListType);
	    listPtr = TclListObjCopy(NULL, listPtr);
	    if (!listPtr) {
		return TCL_ERROR;
	    }
	    copied = 1;
	}
	result = Tcl_ListObjReplace(interp, listPtr, listLen - 1, 1, 0, NULL);
	if (result != TCL_OK) {
	    if (copied) {
		Tcl_DecrRefCount(listPtr);
	    }
2879
2880
2881
2882
2883
2884
2885
2886

2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2873
2874
2875
2876
2877
2878
2879

2880




2881
2882
2883
2884
2885
2886
2887







-
+
-
-
-
-







    }

    /*
     * Make our working copy, then do the actual removes piecemeal.
     */

    if (Tcl_IsShared(listObj)) {
	listObj = TclDuplicatePureObj(interp, listObj, &tclListType);
	listObj = TclListObjCopy(NULL, listObj);
	if (!listObj) {
	    status = TCL_ERROR;
	    goto done;
	}
	copied = 1;
    }
    num = 0;
    first = listLen;
    for (i = 0, prevIdx = -1 ; i < idxc ; i++) {
	Tcl_Size idx = idxv[i];

3135
3136
3137
3138
3139
3140
3141
3142

3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3125
3126
3127
3128
3129
3130
3131

3132



3133
3134
3135
3136
3137
3138
3139







-
+
-
-
-







    /*
     * If the list object is unshared we can modify it directly, otherwise we
     * create a copy to modify: this is "copy on write".
     */

    listPtr = objv[1];
    if (Tcl_IsShared(listPtr)) {
	listPtr = TclDuplicatePureObj(interp, listPtr, &tclListType);
	listPtr = TclListObjCopy(NULL, listPtr);
	if (!listPtr) {
	    return TCL_ERROR;
	}
    }

    /*
     * Note that we call Tcl_ListObjReplace even when numToDelete == 0 and
     * objc == 4. In this case, the list value of listPtr is not changed (no
     * elements are removed or added), but by making the call we are assured
     * we end up with a list in canonical form. Resist any temptation to
4771
4772
4773
4774
4775
4776
4777
4778

4779
4780
4781
4782
4783
4784
4785
4758
4759
4760
4761
4762
4763
4764

4765
4766
4767
4768
4769
4770
4771
4772







-
+







	/*
	 * When sorting using a command, we are reentrant and therefore might
	 * have the representation of the list being sorted shimmered out from
	 * underneath our feet. Take a copy (cheap) to prevent this. [Bug
	 * 1675116]
	 */

	listObj = TclDuplicatePureObj(interp ,listObj, &tclListType);
	listObj = TclListObjCopy(interp, listObj);
	if (listObj == NULL) {
	    sortInfo.resultCode = TCL_ERROR;
	    goto done;
	}

	/*
	 * The existing command is a list. We want to flatten it, append two
5127
5128
5129
5130
5131
5132
5133
5134

5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5114
5115
5116
5117
5118
5119
5120

5121



5122
5123
5124
5125
5126
5127
5128







-
+
-
-
-







    if (first <= last) {
	numToDelete = last - first + 1;
    } else {
	numToDelete = 0;
    }

    if (Tcl_IsShared(listPtr)) {
	listPtr = TclDuplicatePureObj(interp, listPtr, &tclListType);
	listPtr = TclListObjCopy(NULL, listPtr);
	if (!listPtr) {
	    return TCL_ERROR;
	}
	createdNewObj = 1;
    } else {
	createdNewObj = 0;
    }

    result =
	Tcl_ListObjReplace(interp, listPtr, first, numToDelete, objc - 4, objv + 4);
Changes to generic/tclDictObj.c.
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3880
3881
3882
3883
3884
3885
3886

3887
3888
3889
3890
3891
3892
3893







-







 *   operation w/o causing the Obj value to shimmer into a List.
 *
 * Side Effects --
 *
 *   The intent is to have no side effects.
 *
 */

#if 0 /* Needs rewrite */
static int
DictAsListIndex(
    Tcl_Interp *interp,
    struct Tcl_Obj *objPtr,
    Tcl_Size index,
    Tcl_Obj** elemObjPtr)
Changes to generic/tclEnsemble.c.
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
308
309
310
311
312
313
314

315










316
317
318
319
320
321
322







-
+
-
-
-
-
-
-
-
-
-
-








			if (nsPtr->parentPtr) {
			    Tcl_AppendStringsToObj(newCmd, "::", NULL);
			}
			Tcl_AppendObjToObj(newCmd, listv[0]);
			Tcl_ListObjReplace(NULL, newList, 0, 1, 1, &newCmd);
			if (patchedDict == NULL) {
			    patchedDict = TclDuplicatePureObj(
			    patchedDict = Tcl_DuplicateObj(objv[1]);
				interp, objv[1], &tclDictType);
			    if (!patchedDict) {
				if (allocatedMapFlag) {
				    Tcl_DecrRefCount(mapObj);
				}
				Tcl_DecrRefCount(newList);
				Tcl_DecrRefCount(newCmd);
				Tcl_DecrRefCount(patchedDict);
				return TCL_ERROR;
			    }
			}
			Tcl_DictObjPut(NULL, patchedDict, subcmdWordsObj,
				newList);
		    }
		    Tcl_DictObjNext(&search, &subcmdWordsObj, &listObj,
			    &done);
		} while (!done);
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
592
593
594
595
596
597
598

599







600
601
602
603
604
605
606
607
608

609




610
611
612
613
614
615
616







-
+
-
-
-
-
-
-
-









-
+
-
-
-
-







			    if (patchedDict) {
				Tcl_DecrRefCount(patchedDict);
			    }
			    goto freeMapAndError;
			}
			cmd = TclGetString(listv[0]);
			if (!(cmd[0] == ':' && cmd[1] == ':')) {
			    Tcl_Obj *newList = TclDuplicatePureObj(
			    Tcl_Obj *newList = Tcl_DuplicateObj(listObj);
				interp, listObj, &tclListType);
			    if (!newList) {
				if (patchedDict) {
				    Tcl_DecrRefCount(patchedDict);
				}
				goto freeMapAndError;
			    }
			    Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace*)nsPtr);

			    if (nsPtr->parentPtr) {
				Tcl_AppendStringsToObj(newCmd, "::", NULL);
			    }
			    Tcl_AppendObjToObj(newCmd, listv[0]);
			    Tcl_ListObjReplace(NULL, newList, 0, 1, 1,
				    &newCmd);
			    if (patchedDict == NULL) {
				patchedDict = TclDuplicatePureObj(
				patchedDict = Tcl_DuplicateObj(objv[1]);
				    interp, objv[1], &tclListType);
				if (!patchedDict) {
				    goto freeMapAndError;
				}
			    }
			    Tcl_DictObjPut(NULL, patchedDict, subcmdWordsObj,
				    newList);
			}
			Tcl_DictObjNext(&search, &subcmdWordsObj, &listObj,
				&done);
		    } while (!done);
1921
1922
1923
1924
1925
1926
1927
1928

1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1900
1901
1902
1903
1904
1905
1906

1907




1908
1909
1910
1911
1912
1913
1914







-
+
-
-
-
-







				 * Will be freed by the dispatch engine. */
	Tcl_Obj **copyObjv;
	Tcl_Size copyObjc, prefixObjc;

	TclListObjLengthM(NULL, prefixObj, &prefixObjc);

	if (objc == 2) {
	    copyPtr = TclDuplicatePureObj(
	    copyPtr = TclListObjCopy(NULL, prefixObj);
		interp, prefixObj, &tclListType);
	    if (!copyPtr) {
		return TCL_ERROR;
	    }
	} else {
	    copyPtr = Tcl_NewListObj(objc - 2 + prefixObjc, NULL);
	    Tcl_ListObjAppendList(NULL, copyPtr, prefixObj);
	    Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
		    ensemblePtr->numParameters, objv + 1);
	    Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
		    objc - 2 - ensemblePtr->numParameters,
2325
2326
2327
2328
2329
2330
2331
2332
2333

2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2300
2301
2302
2303
2304
2305
2306


2307



2308
2309
2310
2311
2312
2313
2314







-
-
+
-
-
-







    Tcl_Size i, prefixObjc;
    Tcl_Obj **paramv, *unknownCmd, *ensObj;

    /*
     * Create the "unknown" command callback to determine what to do.
     */

    unknownCmd = TclDuplicatePureObj(
	interp, ensemblePtr->unknownHandler, &tclListType);
    unknownCmd = Tcl_DuplicateObj(ensemblePtr->unknownHandler);
    if (!unknownCmd) {
	return TCL_ERROR;
    }
    TclNewObj(ensObj);
    Tcl_GetCommandFullName(interp, ensemblePtr->token, ensObj);
    Tcl_ListObjAppendElement(NULL, unknownCmd, ensObj);
    for (i = 1 ; i < objc ; i++) {
	Tcl_ListObjAppendElement(NULL, unknownCmd, objv[i]);
    }
    TclListObjGetElementsM(NULL, unknownCmd, &paramc, &paramv);
Changes to generic/tclEvent.c.
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
228
229
230
231
232
233
234

235




236
237
238
239
240
241
242







-
+
-
-
-
-







	Tcl_Obj **prefixObjv, **tempObjv;

	/*
	 * Note we copy the handler command prefix each pass through, so we do
	 * support one handler setting another handler.
	 */

	Tcl_Obj *copyObj = TclDuplicatePureObj(
	Tcl_Obj *copyObj = TclListObjCopy(NULL, assocPtr->cmdPrefix);
	    interp, assocPtr->cmdPrefix, &tclListType);
	if (!copyObj) {
	    return;
	}

	errPtr = assocPtr->firstBgPtr;

	TclListObjGetElementsM(NULL, copyObj, &prefixObjc, &prefixObjv);
	tempObjv = (Tcl_Obj**)Tcl_Alloc((prefixObjc+2) * sizeof(Tcl_Obj *));
	memcpy(tempObjv, prefixObjv, prefixObjc*sizeof(Tcl_Obj *));
	tempObjv[prefixObjc] = errPtr->errorMsg;
Changes to generic/tclExecute.c.
3373
3374
3375
3376
3377
3378
3379
3380

3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3373
3374
3375
3376
3377
3378
3379

3380









3381
3382
3383
3384
3385
3386
3387







-
+
-
-
-
-
-
-
-
-
-







    lappendListDirect:
	objResultPtr = varPtr->value.objPtr;
	if (TclListObjLengthM(interp, objResultPtr, &len) != TCL_OK) {
	    TRACE_ERROR(interp);
	    goto gotError;
	}
	if (Tcl_IsShared(objResultPtr)) {
	    Tcl_Obj *newValue;
	    Tcl_Obj *newValue = Tcl_DuplicateObj(objResultPtr);

	    DECACHE_STACK_INFO();
	    newValue = TclDuplicatePureObj(interp, objResultPtr, &tclListType);
	    CACHE_STACK_INFO();

	    if (!newValue) {
		TRACE_ERROR(interp);
		goto gotError;
	    }

	    TclDecrRefCount(objResultPtr);
	    varPtr->value.objPtr = objResultPtr = newValue;
	    Tcl_IncrRefCount(newValue);
	}
	if (TclListObjAppendElements(interp, objResultPtr, objc, objv)
		!= TCL_OK) {
3441
3442
3443
3444
3445
3446
3447
3448
3449

3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3432
3433
3434
3435
3436
3437
3438


3439





3440
3441
3442
3443
3444
3445
3446







-
-
+
-
-
-
-
-







	    if (!objResultPtr) {
		valueToAssign = valuePtr;
	    } else if (TclListObjLengthM(interp, objResultPtr, &len)!=TCL_OK) {
		TRACE_ERROR(interp);
		goto gotError;
	    } else {
		if (Tcl_IsShared(objResultPtr)) {
		    DECACHE_STACK_INFO();
		    valueToAssign = TclDuplicatePureObj(
		    valueToAssign = Tcl_DuplicateObj(objResultPtr);
			interp, objResultPtr, &tclListType);
		    CACHE_STACK_INFO();
		    if (!valueToAssign) {
			goto errorInLappendListPtr;
		    }
		    createdNewObj = 1;
		} else {
		    valueToAssign = objResultPtr;
		}
		if (TclListObjAppendElements(interp, valueToAssign,
			objc, objv) != TCL_OK) {
		    if (createdNewObj) {
6479
6480
6481
6482
6483
6484
6485
6486
6487

6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6464
6465
6466
6467
6468
6469
6470


6471





6472
6473
6474
6475
6476
6477
6478







-
-
+
-
-
-
-
-







	    if (TclListObjLengthM(interp, listPtr, &listLen) != TCL_OK) {
		CACHE_STACK_INFO();
		TRACE_APPEND(("ERROR converting list %" TCL_Z_MODIFIER "d, \"%s\": %s",
			i, O2S(listPtr), O2S(Tcl_GetObjResult(interp))));
		goto gotError;
	    }
	    if (Tcl_IsShared(listPtr)) {
		DECACHE_STACK_INFO();
		objPtr = TclDuplicatePureObj(
		objPtr = TclListObjCopy(NULL, listPtr);
		    interp, listPtr, &tclListType);
		CACHE_STACK_INFO();
		if (!objPtr) {
		    goto gotError;
		}
		Tcl_IncrRefCount(objPtr);
		Tcl_DecrRefCount(listPtr);
		OBJ_AT_DEPTH(listTmpDepth) = objPtr;
	    }
	    iterTmp = (listLen + (numVars - 1))/numVars;
	    if (iterTmp > iterMax) {
		iterMax = iterTmp;
Changes to generic/tclIOGT.c.
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392
393
375
376
377
378
379
380
381

382




383
384
385
386
387
388
389







-
+
-
-
-
-







				 * interpreters. */
{
    Tcl_Obj *resObj;		/* See below, switch (transmit). */
    Tcl_Size resLen = 0;
    unsigned char *resBuf;
    Tcl_InterpState state = NULL;
    int res = TCL_OK;
    Tcl_Obj *command = TclDuplicatePureObj(
    Tcl_Obj *command = TclListObjCopy(NULL, dataPtr->command);
	interp, dataPtr->command, &tclListType);
    if (!command) {
	return TCL_ERROR;
    }
    Tcl_Interp *eval = dataPtr->interp;

    Tcl_Preserve(eval);

    /*
     * Step 1, create the complete command to execute. Do this by appending
     * operation and buffer to operate upon to a copy of the callback
Changes to generic/tclIORChan.c.
2257
2258
2259
2260
2261
2262
2263
2264
2265

2266
2267
2268
2269
2270
2271
2272
2273
2274
2257
2258
2259
2260
2261
2262
2263


2264


2265
2266
2267
2268
2269
2270
2271







-
-
+
-
-







    rcPtr->writeTimer = 0;
#if TCL_THREADS
    rcPtr->thread = Tcl_GetCurrentThread();
#endif
    rcPtr->mode = mode;
    rcPtr->interest = 0;		/* Initially no interest registered */

    rcPtr->cmd = TclDuplicatePureObj(interp, cmdpfxObj, &tclListType);
    if (!rcPtr->cmd) {
    rcPtr->cmd = TclListObjCopy(NULL, cmdpfxObj);
	return NULL;
    }
    Tcl_IncrRefCount(rcPtr->cmd);
    rcPtr->methods = Tcl_NewListObj(METH_WRITE + 1, NULL);
    while (mn <= (int)METH_WRITE) {
	Tcl_ListObjAppendElement(NULL, rcPtr->methods,
		Tcl_NewStringObj(methodNames[mn++], -1));
    }
    Tcl_IncrRefCount(rcPtr->methods);
2397
2398
2399
2400
2401
2402
2403
2404

2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2394
2395
2396
2397
2398
2399
2400

2401



2402
2403
2404
2405
2406
2407
2408







-
+
-
-
-







    }

    /*
     * Insert method into the callback command, after the command prefix,
     * before the channel id.
     */

    cmd = TclDuplicatePureObj(NULL, rcPtr->cmd, &tclListType);
    cmd = TclListObjCopy(NULL, rcPtr->cmd);
    if (!cmd) {
	return TCL_ERROR;
    }
    Tcl_ListObjIndex(NULL, rcPtr->methods, method, &methObj);
    Tcl_ListObjAppendElement(NULL, cmd, methObj);
    Tcl_ListObjAppendElement(NULL, cmd, rcPtr->name);

    /*
     * Append the additional argument containing method specific details
     * behind the channel id. If specified.
Changes to generic/tclInt.h.
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3256
3257
3258
3259
3260
3261
3262


3263
3264
3265
3266
3267
3268
3269







-
-







			    Tcl_CmdDeleteProc *deleteProc);
MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(Tcl_Interp *interp,
			    const char *name, Tcl_Namespace *nameNamespacePtr,
			    Tcl_Namespace *ensembleNamespacePtr, int flags);
MODULE_SCOPE void	TclDeleteNamespaceVars(Namespace *nsPtr);
MODULE_SCOPE void	TclDeleteNamespaceChildren(Namespace *nsPtr);
MODULE_SCOPE Tcl_Size	TclDictGetSize(Tcl_Obj *dictPtr);
MODULE_SCOPE Tcl_Obj *TclDuplicatePureObj(Tcl_Interp *interp,
			    Tcl_Obj * objPtr, const Tcl_ObjType *typPtr);
MODULE_SCOPE int	TclFindDictElement(Tcl_Interp *interp,
			    const char *dict, Tcl_Size dictLength,
			    const char **elementPtr, const char **nextPtr,
			    Tcl_Size *sizePtr, int *literalPtr);
/* TIP #280 - Modified token based evaluation, with line information. */
MODULE_SCOPE int	TclEvalEx(Tcl_Interp *interp, const char *script,
			    Tcl_Size numBytes, int flags, Tcl_Size line,
3388
3389
3390
3391
3392
3393
3394

3395
3396
3397
3398
3399
3400
3401
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400







+







			    Tcl_Obj *listPtr, Tcl_Obj *argPtr);
MODULE_SCOPE Tcl_Obj *	TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr,
			    Tcl_Size indexCount, Tcl_Obj *const indexArray[]);
MODULE_SCOPE Tcl_Obj *	TclListObjGetElement(Tcl_Obj *listObj, Tcl_Size index);
/* TIP #280 */
MODULE_SCOPE void	TclListLines(Tcl_Obj *listObj, Tcl_Size line, Tcl_Size n,
			    Tcl_Size *lines, Tcl_Obj *const *elems);
MODULE_SCOPE Tcl_Obj *	TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr);
MODULE_SCOPE int	TclListObjAppendElements(Tcl_Interp *interp,
			    Tcl_Obj *toObj, Tcl_Size elemCount,
			    Tcl_Obj *const elemObjv[]);
MODULE_SCOPE Tcl_Obj *	TclListObjRange(Tcl_Interp *interp, Tcl_Obj *listPtr,
			    Tcl_Size fromIdx, Tcl_Size toIdx);
MODULE_SCOPE Tcl_Obj *	TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr,
			    Tcl_Obj *indexPtr, Tcl_Obj *valuePtr);
Changes to generic/tclListObj.c.
1311
1312
1313
1314
1315
1316
1317












































1318
1319
1320
1321
1322
1323
1324
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	ListObjReplaceRepAndInvalidate(objPtr, &listRep);
    } else {
	TclFreeInternalRep(objPtr);
	TclInvalidateStringRep(objPtr);
	Tcl_InitStringRep(objPtr, NULL, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclListObjCopy --
 *
 *	Makes a "pure list" copy of a list value. This provides for the C
 *	level a counterpart of the [lrange $list 0 end] command, while using
 *	internals details to be as efficient as possible.
 *
 * Results:
 *	Normally returns a pointer to a new Tcl_Obj, that contains the same
 *	list value as *listPtr does. The returned Tcl_Obj has a refCount of
 *	zero. If *listPtr does not hold a list, NULL is returned, and if
 *	interp is non-NULL, an error message is recorded there.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclListObjCopy(
    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
    Tcl_Obj *listObj)		/* List object for which an element array is
				 * to be returned. */
{
    Tcl_Obj *copyObj;

    if (!TclHasInternalRep(listObj, &tclListType)) {
	if (TclObjTypeHasProc(listObj, lengthProc)) {
	    return Tcl_DuplicateObj(listObj);
	}
	if (SetListFromAny(interp, listObj) != TCL_OK) {
	    return NULL;
	}
    }

    TclNewObj(copyObj);
    TclInvalidateStringRep(copyObj);
    DupListInternalRep(listObj, copyObj);
    return copyObj;
}

/*
 *------------------------------------------------------------------------
 *
 * ListRepRange --
 *
 *	Initializes a ListRep as a range within the passed ListRep.
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557









2558
2559
2560
2561


2562
2563
2564
2565
2566
2567
2568
2569
2570

2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2568
2569
2570
2571
2572
2573
2574

2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591









2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602


2603
2604
2605
2606
2607
2608
2609
2610
2611


2612









2613
2614
2615
2616
2617
2618
2619







-

















-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+


-
-
+
+







-
-
+
-
-
-
-
-
-
-
-
-







    Tcl_Obj *listObj,		/* List being unpacked. */
    Tcl_Obj *argObj)		/* Index or index list. */
{
    Tcl_Size index;			/* Index into the list. */
    Tcl_Obj *indexListCopy;
    Tcl_Obj **indexObjs;
    Tcl_Size numIndexObjs;
    int status;

    /*
     * Determine whether argPtr designates a list or a single index. We have
     * to be careful about the order of the checks to avoid repeated
     * shimmering; if internal rep is already a list do not shimmer it.
     * see TIP#22 and TIP#33 for the details.
     */
    if (!TclHasInternalRep(argObj, &tclListType)
	&& TclGetIntForIndexM(NULL, argObj, TCL_SIZE_MAX - 1, &index)
	       == TCL_OK) {
	/*
	 * argPtr designates a single index.
	 */
	return TclLindexFlat(interp, listObj, 1, &argObj);
    }

    /*
     * Make a private copy of the index list argument to keep the internal
     * representation of the indices array unchanged while it is in use.  This
     * is probably unnecessary. It does not appear that any damaging change to
     * the internal representation is possible, and no test has been devised to
     * show any error when this private copy is not made, But it's cheap, and
     * it offers some future-proofing insurance in case the TclLindexFlat
     * implementation changes in some unexpected way, or some new form of trace
     * or callback permits things to happen that the current implementation
     * does not.
     * Here we make a private copy of the index list argument to avoid any
     * shimmering issues that might invalidate the indices array below while
     * we are still using it. This is probably unnecessary. It does not appear
     * that any damaging shimmering is possible, and no test has been devised
     * to show any error when this private copy is not made. But it's cheap,
     * and it offers some future-proofing insurance in case the TclLindexFlat
     * implementation changes in some unexpected way, or some new form of
     * trace or callback permits things to happen that the current
     * implementation does not.
     */

    indexListCopy = TclDuplicatePureObj(interp, argObj, &tclListType);
    if (!indexListCopy) {
    indexListCopy = TclListObjCopy(NULL, argObj);
    if (indexListCopy == NULL) {
	/*
	 * The argument is neither an index nor a well-formed list.
	 * Report the error via TclLindexFlat.
	 * TODO - This is as original code. why not directly return an error?
	 */
	return TclLindexFlat(interp, listObj, 1, &argObj);
    }
    status = TclListObjGetElementsM(
	interp, indexListCopy, &numIndexObjs, &indexObjs);
    TclListObjGetElementsM(interp, indexListCopy, &numIndexObjs, &indexObjs);
    if (status != TCL_OK) {
	Tcl_DecrRefCount(indexListCopy);
	/*
	 * The argument is neither an index nor a well-formed list.
	 * Report the error via TclLindexFlat.
	 * TODO - This is as original code. why not directly return an error?
	 */
	return TclLindexFlat(interp, listObj, 1, &argObj);
    }
    listObj = TclLindexFlat(interp, listObj, numIndexObjs, indexObjs);
    Tcl_DecrRefCount(indexListCopy);
    return listObj;
}

/*
 *----------------------------------------------------------------------
2764
2765
2766
2767
2768
2769
2770
2771

2772
2773
2774
2775
2776
2777
2778
2779
2797
2798
2799
2800
2801
2802
2803

2804

2805
2806
2807
2808
2809
2810
2811







-
+
-







	    /* indexArgPtr designates a single index. */
	    /* T:listrep-1.{2.1,12.1,15.1,19.1},2.{2.3,9.3,10.1,13.1,16.1}, 3.{4,5,6}.3 */
	    retValueObj = TclLsetFlat(interp, listObj, 1, &indexArgObj, valueObj);
	}

    } else {

	indexListCopy = TclDuplicatePureObj(
	indexListCopy = TclListObjCopy(NULL,indexArgObj);
	    interp, indexArgObj, &tclListType);
	if (!indexListCopy) {
	    /*
	     * indexArgPtr designates something that is neither an index nor a
	     * well formed list. Report the error via TclLsetFlat.
	     */
	    retValueObj = TclLsetFlat(interp, listObj, 1, &indexArgObj, valueObj);
	} else {
2844
2845
2846
2847
2848
2849
2850
2851

2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872








2873
2874
2875

2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2876
2877
2878
2879
2880
2881
2882

2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902


2903
2904
2905
2906
2907
2908
2909
2910
2911
2912

2913




2914
2915
2916
2917
2918
2919
2920







-
+



















-
-
+
+
+
+
+
+
+
+


-
+
-
-
-
-







    Tcl_Obj *listObj,		/* Pointer to the list being modified. */
    Tcl_Size indexCount,		/* Number of index args. */
    Tcl_Obj *const indexArray[],
				/* Index args. */
    Tcl_Obj *valueObj)		/* Value arg to 'lset' or NULL to 'lpop'. */
{
    Tcl_Size index, len;
    int copied = 0, result;
    int result;
    Tcl_Obj *subListObj, *retValueObj;
    Tcl_Obj *pendingInvalidates[10];
    Tcl_Obj **pendingInvalidatesPtr = pendingInvalidates;
    Tcl_Size numPendingInvalidates = 0;

    /*
     * If there are no indices, simply return the new value.  (Without
     * indices, [lset] is a synonym for [set].
     * [lpop] does not use this but protect for NULL valueObj just in case.
     */

    if (indexCount == 0) {
	if (valueObj != NULL) {
	    Tcl_IncrRefCount(valueObj);
	}
	return valueObj;
    }

    /*
     * If the list is shared, make a copy to modify (copy-on-write). The string
     * representation and internal representation of listObj remains unchanged.
     * If the list is shared, make a copy we can modify (copy-on-write).  We
     * use Tcl_DuplicateObj() instead of TclListObjCopy() for a few reasons:
     * 1) we have not yet confirmed listObj is actually a list; 2) We make a
     * verbatim copy of any existing string rep, and when we combine that with
     * the delayed invalidation of string reps of modified Tcl_Obj's
     * implemented below, the outcome is that any error condition that causes
     * this routine to return NULL, will leave the string rep of listObj and
     * all elements to be unchanged.
     */

    subListObj = Tcl_IsShared(listObj)
    subListObj = Tcl_IsShared(listObj) ? Tcl_DuplicateObj(listObj) : listObj;
	? TclDuplicatePureObj(interp, listObj, &tclListType) : listObj;
    if (!subListObj) {
	return NULL;
    }

    /*
     * Anchor the linked list of Tcl_Obj's whose string reps must be
     * invalidated if the operation succeeds.
     */

    retValueObj = subListObj;
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959




2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970

2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994

2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
2984
2985
2986
2987
2988
2989
2990



2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004

3005





3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022


3023









3024
3025
3026
3027
3028
3029
3030







-
-
-
+
+
+
+










-
+
-
-
-
-
-

















-
-
+
-
-
-
-
-
-
-
-
-







		                 NULL);
	    }
	    result = TCL_ERROR;
	    break;
	}

	/*
	 * No error conditions.  If this is not the last index, determine the
	 * next sublist for the next pass through the loop, and take steps to
	 * make sure it is unshared in order to modify it.
	 * No error conditions.  As long as we're not yet on the last index,
	 * determine the next sublist for the next pass through the loop,
	 * and take steps to make sure it is an unshared copy, as we intend
	 * to modify it.
	 */

	if (--indexCount) {
	    parentList = subListObj;
	    if (index == elemCount) {
		TclNewObj(subListObj);
	    } else {
		subListObj = elemPtrs[index];
	    }
	    if (Tcl_IsShared(subListObj)) {
		subListObj = TclDuplicatePureObj(
		subListObj = Tcl_DuplicateObj(subListObj);
		    interp, subListObj, &tclListType);
		if (!subListObj) {
		    return NULL;
		}
		copied = 1;
	    }

	    /*
	     * Replace the original elemPtr[index] in parentList with a copy
	     * we know to be unshared.  This call will also deal with the
	     * situation where parentList shares its internalrep with other
	     * Tcl_Obj's.  Dealing with the shared internalrep case can
	     * cause subListObj to become shared again, so detect that case
	     * and make and store another copy.
	     */

	    if (index == elemCount) {
		Tcl_ListObjAppendElement(NULL, parentList, subListObj);
	    } else {
		TclListObjSetElement(NULL, parentList, index, subListObj);
	    }
	    if (Tcl_IsShared(subListObj)) {
		Tcl_Obj * newSubListObj;
		newSubListObj = TclDuplicatePureObj(
		subListObj = Tcl_DuplicateObj(subListObj);
		    interp, subListObj, &tclListType);
		if (copied) {
		    Tcl_DecrRefCount(subListObj);
		}
		if (newSubListObj) {
		    subListObj = newSubListObj;
		} else {
		    return NULL;
		}
		TclListObjSetElement(NULL, parentList, index, subListObj);
	    }

	    /*
	     * The TclListObjSetElement() calls do not spoil the string rep
	     * of parentList, and that's fine for now, since all we've done
	     * so far is replace a list element with an unshared copy.  The
Changes to generic/tclObj.c.
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
198
199
200
201
202
203
204



205
206
207
208
209
210
211







-
-
-







static void		UpdateStringOfDouble(Tcl_Obj *objPtr);
static void		UpdateStringOfInt(Tcl_Obj *objPtr);
static void		FreeBignum(Tcl_Obj *objPtr);
static void		DupBignum(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
static void		UpdateStringOfBignum(Tcl_Obj *objPtr);
static int		GetBignumFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
			    int copy, mp_int *bignumValue);
static int		SetDuplicatePureObj(Tcl_Interp *interp,
			    Tcl_Obj *dupPtr, Tcl_Obj *objPtr,
			    const Tcl_ObjType *typePtr);

/*
 * Prototypes for the array hash key methods.
 */

static Tcl_HashEntry *	AllocObjEntry(Tcl_HashTable *tablePtr, void *keyPtr);

1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1522
1523
1524
1525
1526
1527
1528








1529
1530
1531
1532
1533
1534
1535







-
-
-
-
-
-
-
-







 *----------------------------------------------------------------------
 *
 * Tcl_DuplicateObj --
 *
 *	Create and return a new object that is a duplicate of the argument
 *	object.
 *
 * TclDuplicatePureObj --
 *	Like Tcl_DuplicateObj, except that it converts the duplicate to the
 *	specifid typ, does not duplicate the 'bytes'
 *	field unless it is necessary, i.e. the duplicated Tcl_Obj provides no
 *	updateStringProc.  This can avoid an expensive memory allocation since
 *	the data in the 'bytes' field of each Tcl_Obj must reside in allocated
 *	memory.
 *
 * Results:
 *	The return value is a pointer to a newly created Tcl_Obj. This object
 *	has reference count 0 and the same type, if any, as the source object
 *	objPtr. Also:
 *	  1) If the source object has a valid string rep, we copy it;
 *	     otherwise, the duplicate's string rep is set NULL to mark it
 *	     invalid.
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1572
1573
1574
1575
1576
1577
1578











































































































1579
1580
1581
1582
1583
1584
1585







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







{
    Tcl_Obj *dupPtr;

    TclNewObj(dupPtr);
    SetDuplicateObj(dupPtr, objPtr);
    return dupPtr;
}


/*
 *----------------------------------------------------------------------
 *
 * TclDuplicatePureObj --
 *
 *	Duplicates a Tcl_Obj and converts the internal representation of the
 *	duplicate to the given type, changing neither the 'bytes' field
 *	nor the internal representation of the original object, and without
 *	duplicating the bytes field unless necessary, i.e. unless the
 *	duplicate provides no updateStringProc after conversion.  This can
 *	avoid an expensive memory allocation since the data in the 'bytes'
 *	field of each Tcl_Obj must reside in allocated memory.
 *
 * Results:
 *	A pointer to a newly-created Tcl_Obj or NULL if there was an error.
 *	This object has reference count 0.  Also:
 *
 *----------------------------------------------------------------------
 */
int SetDuplicatePureObj(
    Tcl_Interp *interp,
    Tcl_Obj *dupPtr,
    Tcl_Obj *objPtr,
    const Tcl_ObjType *typePtr)
{
    char *bytes = objPtr->bytes;
    int status = TCL_OK;
    const Tcl_ObjType *useTypePtr =
        objPtr->typePtr ? objPtr->typePtr : typePtr;

    TclInvalidateStringRep(dupPtr);
    assert(dupPtr->typePtr == NULL);

    if (objPtr->typePtr && objPtr->typePtr->dupIntRepProc) {
	objPtr->typePtr->dupIntRepProc(objPtr, dupPtr);
    } else {
	dupPtr->internalRep = objPtr->internalRep;
	dupPtr->typePtr = objPtr->typePtr;
    }

    if (typePtr != NULL && dupPtr->typePtr != useTypePtr) {
	if (bytes) {
	    dupPtr->bytes = bytes;
	    dupPtr->length = objPtr->length;
	}
	/* borrow bytes from original object */
	status = Tcl_ConvertToType(interp, dupPtr, useTypePtr);
	if (bytes) {
	    dupPtr->bytes = NULL;
	    dupPtr->length = 0;
	}
	if (status != TCL_OK) {
	    return status;
	}
    }

    /* tclStringType is treated as a special case because a Tcl_Obj having this
     * type can not always update the string representation.  This happens, for
     * example, when Tcl_GetCharLength() converts the internal representation
     * to tclStringType in order to store the number of characters, but does
     * not store enough information to generate the string representation.
     *
     * Perhaps in the future this can be remedied and this special treatment
     * removed.
     */


    if (bytes && (dupPtr->typePtr == NULL
	|| dupPtr->typePtr->updateStringProc == NULL
	|| useTypePtr == &tclStringType
	)
    ) {
	if (!TclAttemptInitStringRep(dupPtr, bytes, objPtr->length)) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"insufficient memory to initialize string", -1));
		Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
	    }
	    status = TCL_ERROR;
	}
    }
    return status;
}

Tcl_Obj *
TclDuplicatePureObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    const Tcl_ObjType *typePtr
)		/* The object to duplicate. */
{
    int status;
    Tcl_Obj *dupPtr;

    TclNewObj(dupPtr);
    status = SetDuplicatePureObj(interp, dupPtr, objPtr, typePtr);
    if (status == TCL_OK) {
	return dupPtr;
    } else {
	Tcl_DecrRefCount(dupPtr);
	return NULL;
    }
}



void
TclSetDuplicateObj(
    Tcl_Obj *dupPtr,
    Tcl_Obj *objPtr)
{
    if (Tcl_IsShared(dupPtr)) {
Changes to generic/tclUtil.c.
2006
2007
2008
2009
2010
2011
2012
2013

2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2006
2007
2008
2009
2010
2011
2012

2013




2014
2015
2016
2017
2018
2019
2020







-
+
-
-
-
-







		    /* Abandon ship! */
		    Tcl_DecrRefCount(resPtr);
		    Tcl_BounceRefCount(elemPtr); // could be an abstract list element
		    goto slow;
		}
		Tcl_BounceRefCount(elemPtr); // could be an an abstract list element
	    } else {
		resPtr = TclDuplicatePureObj(
		resPtr = TclListObjCopy(NULL, objPtr);
		    NULL, objPtr, &tclListType);
		if (!resPtr) {
		    return NULL;
		}
	    }
	}
	if (!resPtr) {
	    TclNewObj(resPtr);
	}
	return resPtr;
    }
Changes to generic/tclVar.c.
3095
3096
3097
3098
3099
3100
3101
3102

3103
3104
3105
3106
3107
3108
3109
3095
3096
3097
3098
3099
3100
3101

3102
3103
3104
3105
3106
3107
3108
3109







-
+







    ArrayPopulateSearch(interp, arrayNameObj, varPtr, searchPtr);

    /*
     * Make sure that these objects (which we need throughout the body of the
     * loop) don't vanish.
     */

    varListObj = TclDuplicatePureObj(interp, objv[1], &tclListType);
    varListObj = TclListObjCopy(NULL, objv[1]);
    if (!varListObj) {
	return TCL_ERROR;
    }
    scriptObj = objv[3];
    Tcl_IncrRefCount(scriptObj);

    /*
4071
4072
4073
4074
4075
4076
4077
4078

4079
4080
4081
4082
4083
4084
4085
4086
4071
4072
4073
4074
4075
4076
4077

4078

4079
4080
4081
4082
4083
4084
4085







-
+
-








	/*
	 * We needn't worry about traces invalidating arrayPtr: should that be
	 * the case, TclPtrSetVarIdx will return NULL so that we break out of
	 * the loop and return an error.
	 */

	copyListObj =
	copyListObj = TclListObjCopy(NULL, arrayElemObj);
	    TclDuplicatePureObj(interp, arrayElemObj, &tclListType);
	if (!copyListObj) {
	    return TCL_ERROR;
	}
	for (i=0 ; i<elemLen ; i+=2) {
	    Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
		    elemPtrs[i], TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);