Check-in [76da711d71]
Not logged in

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

Overview
Comment:Make the check to avoid generating a string representation in [uplevel] a little less intrusive.
Timelines: family | ancestors | descendants | both | core-8-6-branch
Files: files | file ages | folders
SHA3-256: 76da711d7172c54a9a10a11086afc159e5310bc0210fd4012e8b889749b2392d
User & Date: pooryorick 2020-09-20 10:38:41.072
References
2020-09-20
13:47 Ticket [b9ecf3ce98] uplevel $list, uplevel 1 $list and generation of string representations status still Open with 3 other changes artifact: 114b3a249c user: pooryorick
Context
2020-09-20
15:53
Silence compiler warning -- fix safety of macro. check-in: f3d1acd780 user: dgp tags: core-8-6-branch
10:38
Make the check to avoid generating a string representation in [uplevel] a little less intrusive. check-in: 76da711d71 user: pooryorick tags: core-8-6-branch
10:21
Merge 8.5 check-in: 4df01802b3 user: jan.nijtmans tags: core-8-6-branch
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to generic/tclInt.h.
4371
4372
4373
4374
4375
4376
4377



4378
4379
4380
4381
4382
4383
4384
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387







+
+
+







#define TclInvalidateStringRep(objPtr) \
    if (objPtr->bytes != NULL) { \
	if (objPtr->bytes != tclEmptyStringRep) { \
	    ckfree((char *) objPtr->bytes); \
	} \
	objPtr->bytes = NULL; \
    }

#define TclHasStringRep(objPtr) \
    objPtr->bytes != NULL

/*
 *----------------------------------------------------------------
 * Macros used by the Tcl core to grow Tcl_Token arrays. They use the same
 * growth algorithm as used in tclStringObj.c for growing strings. The ANSI C
 * "prototype" for this macro is:
 *
Changes to generic/tclProc.c.
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915

916
917
918
919
920
921
922
923
924
925
926
927

928
929
930
931
932
933
934



935
936
937
938
939
940
941
942
943
944
945
946











947
948
949
950
951
952
953
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921
922
923

924
925
926
927
928
929




930
931
932
933











934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951







-













-
+









-


+



-
-
-
-
+
+
+

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







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{

    Interp *iPtr = (Interp *) interp;
    CmdFrame *invoker = NULL;
    int word = 0;
    int havelevel = 0;
    int result;
    CallFrame *savedVarFramePtr, *framePtr;
    Tcl_Obj *objPtr;

    if (objc < 2) {
    /* to do 
    *    simplify things by interpreting the argument as a command when there
    *    is only one argument.  This requires a TIP since currently a single
    *    argument is interpreted as a level indicator if possible.
    */
    uplevelSyntax:
	Tcl_WrongNumArgs(interp, 1, objv, "?level? command ?arg ...?");
	return TCL_ERROR;
    } else if (objc == 2) {
    } else if (!TclHasStringRep(objv[1]) && objc == 2) {
	int status ,llength;
	status = Tcl_ListObjLength(interp, objv[1], &llength);
	if (status == TCL_OK && llength > 1) {
	    /* the first argument can't interpreted as a level. Avoid
	     * generating a string representation of the script. */
	    result = TclGetFrame(interp, "1", &framePtr);
	    if (result == -1) {
		return TCL_ERROR;
	    }
	    havelevel = 1;
	    objc -= 1;
	    objv += 1;
	    goto havelevel;
	}
    }

    if (!havelevel) {
	/*
	 * Find the level to use for executing the command.
	 */
    /*
     * Find the level to use for executing the command.
     */

	result = TclObjGetFrame(interp, objv[1], &framePtr);
	if (result == -1) {
	    return TCL_ERROR;
	}
	objc -= result + 1;
	if (objc == 0) {
	    goto uplevelSyntax;
	}
	objv += result + 1;
    }

    result = TclObjGetFrame(interp, objv[1], &framePtr);
    if (result == -1) {
	return TCL_ERROR;
    }
    objc -= result + 1;
    if (objc == 0) {
	goto uplevelSyntax;
    }
    objv += result + 1;

    havelevel:

    /*
     * Modify the interpreter state to execute in the given frame.
     */

    savedVarFramePtr = iPtr->varFramePtr;
    iPtr->varFramePtr = framePtr;