Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix memory leaks and remove unnecessary reference count bounce. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | main |
Files: | files | file ages | folders |
SHA3-256: |
427bc951fbcffe81aeaf6ad765e84bd0 |
User & Date: | pooryorick 2023-05-16 09:33:12.551 |
References
2023-05-17
| ||
15:22 | • New ticket [6022b9f946] Tk when built against Tcl 9.0 broken. artifact: cb3a25bc39 user: jan.nijtmans | |
Context
2023-05-17
| ||
16:12 | Merge trunk check-in: 3e44e4bdd3 user: griffin tags: tip-636-tcl9-644 | |
07:30 | Remove dead code check-in: a00f23f242 user: jan.nijtmans tags: trunk, main | |
2023-05-16
| ||
09:33 | Fix memory leaks and remove unnecessary reference count bounce. check-in: 427bc951fb user: pooryorick tags: trunk, main | |
06:25 | Merge 8.7 check-in: 8e4d8a6053 user: jan.nijtmans tags: trunk, main | |
Changes
Changes to generic/tclCmdIL.c.
︙ | ︙ | |||
2464 2465 2466 2467 2468 2469 2470 | TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *listPtr; Tcl_Size len, index; | | | 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 | TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *listPtr; Tcl_Size len, index; int copied = 0, result; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "list index ?element ...?"); return TCL_ERROR; } result = TclListObjLengthM(interp, objv[1], &len); |
︙ | ︙ | |||
2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 | * 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(listPtr); } if ((objc == 4) && (index == len)) { /* * Special case: insert one element at the end of the list. */ result = Tcl_ListObjAppendElement(NULL, listPtr, objv[3]); if (result != TCL_OK) { return result; } } else { if (TCL_OK != Tcl_ListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]))) { return TCL_ERROR; } } /* * Set the interpreter's object result. */ | > > > > > > > | 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 | * 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(listPtr); copied = 1; } if ((objc == 4) && (index == len)) { /* * Special case: insert one element at the end of the list. */ result = Tcl_ListObjAppendElement(NULL, listPtr, objv[3]); if (result != TCL_OK) { if (copied) { Tcl_DecrRefCount(listPtr); } return result; } } else { if (TCL_OK != Tcl_ListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]))) { if (copied) { Tcl_DecrRefCount(listPtr); } return TCL_ERROR; } } /* * Set the interpreter's object result. */ |
︙ | ︙ | |||
2635 2636 2637 2638 2639 2640 2641 | TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Size listLen; | | | 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 | TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Size listLen; int copied = 0, result; Tcl_Obj *elemPtr, *stored; Tcl_Obj *listPtr, **elemPtrs; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "listvar ?index?"); return TCL_ERROR; } |
︙ | ︙ | |||
2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 | * Second, remove the element. * TclLsetFlat adds a ref count which is handled. */ if (objc == 2) { if (Tcl_IsShared(listPtr)) { listPtr = TclDuplicatePureObj(listPtr); } result = Tcl_ListObjReplace(interp, listPtr, listLen - 1, 1, 0, NULL); if (result != TCL_OK) { return result; } Tcl_IncrRefCount(listPtr); } else { | > > > > | > > > | < > > | 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 | * Second, remove the element. * TclLsetFlat adds a ref count which is handled. */ if (objc == 2) { if (Tcl_IsShared(listPtr)) { listPtr = TclDuplicatePureObj(listPtr); copied = 1; } result = Tcl_ListObjReplace(interp, listPtr, listLen - 1, 1, 0, NULL); if (result != TCL_OK) { if (copied) { Tcl_DecrRefCount(listPtr); } return result; } Tcl_IncrRefCount(listPtr); } else { Tcl_Obj *newListPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL); if (newListPtr == NULL) { if (copied) { Tcl_DecrRefCount(listPtr); } return TCL_ERROR; } else { listPtr = newListPtr; } } stored = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG); Tcl_DecrRefCount(listPtr); if (stored == NULL) { return TCL_ERROR; |
︙ | ︙ | |||
2820 2821 2822 2823 2824 2825 2826 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Size i, idxc, prevIdx, first, num; Tcl_Size *idxv, listLen; Tcl_Obj *listObj; | | | 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 | Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Size i, idxc, prevIdx, first, num; Tcl_Size *idxv, listLen; Tcl_Obj *listObj; int copied = 0, status = TCL_OK; /* * Parse the arguments. */ if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "list ?index ...?"); |
︙ | ︙ | |||
2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 | /* * Make our working copy, then do the actual removes piecemeal. */ if (Tcl_IsShared(listObj)) { listObj = TclDuplicatePureObj(listObj); } num = 0; first = listLen; for (i = 0, prevIdx = -1 ; i < idxc ; i++) { Tcl_Size idx = idxv[i]; /* | > | 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 | /* * Make our working copy, then do the actual removes piecemeal. */ if (Tcl_IsShared(listObj)) { listObj = TclDuplicatePureObj(listObj); copied = 1; } num = 0; first = listLen; for (i = 0, prevIdx = -1 ; i < idxc ; i++) { Tcl_Size idx = idxv[i]; /* |
︙ | ︙ | |||
2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 | num = 1; first = idx; } } if (num != 0) { status = Tcl_ListObjReplace(interp, listObj, first, num, 0, NULL); if (status != TCL_OK) { goto done; } } Tcl_SetObjResult(interp, listObj); done: Tcl_Free(idxv); return status; | > > > | 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 | num = 1; first = idx; } } if (num != 0) { status = Tcl_ListObjReplace(interp, listObj, first, num, 0, NULL); if (status != TCL_OK) { if (copied) { Tcl_DecrRefCount(listObj); } goto done; } } Tcl_SetObjResult(interp, listObj); done: Tcl_Free(idxv); return status; |
︙ | ︙ | |||
5105 5106 5107 5108 5109 5110 5111 | Tcl_DecrRefCount(listPtr); } return result; } /* * Tcl_ObjSetVar2 may return a value different from listPtr in the | | < < < < < < < < | 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 | Tcl_DecrRefCount(listPtr); } return result; } /* * Tcl_ObjSetVar2 may return a value different from listPtr in the * presence of traces etc. */ finalValuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG); if (finalValuePtr == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, finalValuePtr); return TCL_OK; } |
︙ | ︙ |