Subject: Spare developers the burden and error risk of counting bytes in string literals, or having to type them twice.

From: dgp <[email-masked]>
Date: Thu, 23 May 2013 20:24:56 +0000

---
 generic/tclCompCmds.c   | 72 +++++++++++++++++++++++--------------------------
 generic/tclCompCmdsGR.c | 44 +++++++++++++++---------------
 generic/tclCompCmdsSZ.c | 34 ++++++++++++-----------
 generic/tclCompile.h    |  8 ++++--
 4 files changed, 81 insertions(+), 77 deletions(-)

diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index e4b1087..10faff7 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -295,7 +295,7 @@ TclCompileArraySetCmd(
 	    envPtr->currStackDepth = savedStackDepth;
 	    TclEmitOpcode(  INST_POP,				envPtr);
 	}
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	goto done;
     }
 
@@ -305,14 +305,12 @@ TclCompileArraySetCmd(
 
     if (isDataValid && !isDataEven) {
 	savedStackDepth = envPtr->currStackDepth;
-	PushLiteral(envPtr, "list must have an even number of elements",
-		strlen("list must have an even number of elements"));
-	PushLiteral(envPtr, "-errorCode {TCL ARGUMENT FORMAT}",
-		strlen("-errorCode {TCL ARGUMENT FORMAT}"));
+	PushStringLiteral(envPtr, "list must have an even number of elements");
+	PushStringLiteral(envPtr, "-errorCode {TCL ARGUMENT FORMAT}");
 	TclEmitInstInt4(INST_RETURN_IMM, 1,			envPtr);
 	TclEmitInt4(		0,				envPtr);
 	envPtr->currStackDepth = savedStackDepth;
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	goto done;
     }
 
@@ -376,15 +374,13 @@ TclCompileArraySetCmd(
 
 	TclEmitOpcode(	INST_DUP,				envPtr);
 	TclEmitOpcode(	INST_LIST_LENGTH,			envPtr);
-	PushLiteral(envPtr, "1", 1);
+	PushStringLiteral(envPtr, "1");
 	TclEmitOpcode(	INST_BITAND,				envPtr);
 	offsetFwd = CurrentOffset(envPtr);
 	TclEmitInstInt1(INST_JUMP_FALSE1, 0,			envPtr);
 	savedStackDepth = envPtr->currStackDepth;
-	PushLiteral(envPtr, "list must have an even number of elements",
-		strlen("list must have an even number of elements"));
-	PushLiteral(envPtr, "-errorCode {TCL ARGUMENT FORMAT}",
-		strlen("-errorCode {TCL ARGUMENT FORMAT}"));
+	PushStringLiteral(envPtr, "list must have an even number of elements");
+	PushStringLiteral(envPtr, "-errorCode {TCL ARGUMENT FORMAT}");
 	TclEmitInstInt4(INST_RETURN_IMM, 1,			envPtr);
 	TclEmitInt4(		0,				envPtr);
 	envPtr->currStackDepth = savedStackDepth;
@@ -441,7 +437,7 @@ TclCompileArraySetCmd(
 	TclEmitInstInt1(INST_UNSET_SCALAR, 0,			envPtr);
 	TclEmitInt4(		dataVar,			envPtr);
     }
-    PushLiteral(envPtr,	"", 0);
+    PushStringLiteral(envPtr,	"");
   done:
     Tcl_DecrRefCount(literalObj);
     return TCL_OK;
@@ -485,7 +481,7 @@ TclCompileArrayUnsetCmd(
 	envPtr->currStackDepth = savedStackDepth;
 	TclEmitOpcode(	INST_POP,				envPtr);
     }
-    PushLiteral(envPtr,	"", 0);
+    PushStringLiteral(envPtr,	"");
     return TCL_OK;
 }
 
@@ -525,7 +521,7 @@ TclCompileBreakCmd(
      */
 
     TclEmitOpcode(INST_BREAK, envPtr);
-    PushLiteral(envPtr, "", 0);	/* Evil hack! */
+    PushStringLiteral(envPtr, "");	/* Evil hack! */
     return TCL_OK;
 }
 
@@ -674,7 +670,7 @@ TclCompileCatchCmd(
 	 */
 
 	TclEmitOpcode(		INST_POP,			envPtr);
-	PushLiteral(envPtr, "0", 1);
+	PushStringLiteral(envPtr, "0");
 	TclEmitInstInt1(	INST_JUMP1, 3,			envPtr);
 	envPtr->currStackDepth = savedStackDepth;
 	ExceptionRangeTarget(envPtr, range, catchOffset);
@@ -696,7 +692,7 @@ TclCompileCatchCmd(
      * and jump around the "error case" code.
      */
 
-    PushLiteral(envPtr, "0", 1);
+    PushStringLiteral(envPtr, "0");
     TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
     /* Stack at this point: ?script? <mark> result TCL_OK */
 
@@ -832,7 +828,7 @@ TclCompileContinueCmd(
      */
 
     TclEmitOpcode(INST_CONTINUE, envPtr);
-    PushLiteral(envPtr, "", 0);	/* Evil hack! */
+    PushStringLiteral(envPtr, "");	/* Evil hack! */
     return TCL_OK;
 }
 
@@ -1208,7 +1204,7 @@ TclCompileDictCreateCmd(
 	return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
     }
 
-    PushLiteral(envPtr,		"", 0);
+    PushStringLiteral(envPtr,		"");
     Emit14Inst(			INST_STORE_SCALAR, worker,	envPtr);
     TclEmitOpcode(		INST_POP,			envPtr);
     tokenPtr = TokenAfter(parsePtr->tokenPtr);
@@ -1247,7 +1243,7 @@ TclCompileDictMergeCmd(
      */
 
     if (parsePtr->numWords < 2) {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	return TCL_OK;
     } else if (parsePtr->numWords == 2) {
 	tokenPtr = TokenAfter(parsePtr->tokenPtr);
@@ -1477,7 +1473,7 @@ CompileDictEachCmd(
      */
 
     if (collect == TCL_EACH_COLLECT) {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	Emit14Inst(	INST_STORE_SCALAR, collectVar,		envPtr);
 	TclEmitOpcode(	INST_POP,				envPtr);
     }
@@ -1615,7 +1611,7 @@ CompileDictEachCmd(
 	TclEmitInstInt1(INST_UNSET_SCALAR, 0,			envPtr);
 	TclEmitInt4(		collectVar,			envPtr);
     } else {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
     return TCL_OK;
 }
@@ -1991,18 +1987,18 @@ TclCompileDictWithCmd(
 		TclEmitInstInt4(INST_OVER, 1,			envPtr);
 		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
 		TclEmitInstInt4(INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 	    } else {
 		/*
 		 * Case: Direct dict in LVT with empty body.
 		 */
 
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 		Emit14Inst(	INST_LOAD_SCALAR, dictVar,	envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
 		TclEmitInstInt4(INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 	    }
 	} else {
 	    if (gotPath) {
@@ -2021,7 +2017,7 @@ TclCompileDictWithCmd(
 		TclEmitInstInt4(INST_OVER, 1,			envPtr);
 		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
 		TclEmitOpcode(	INST_DICT_RECOMBINE_STK,	envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 	    } else {
 		/*
 		 * Case: Direct dict in non-simple var with empty body.
@@ -2030,12 +2026,12 @@ TclCompileDictWithCmd(
 		CompileWord(envPtr, varTokenPtr, interp, 0);
 		TclEmitOpcode(	INST_DUP,			envPtr);
 		TclEmitOpcode(	INST_LOAD_STK,			envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 		TclEmitInstInt4(INST_REVERSE, 2,		envPtr);
 		TclEmitOpcode(	INST_DICT_RECOMBINE_STK,	envPtr);
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 	    }
 	}
 	envPtr->currStackDepth = savedStackDepth + 1;
@@ -2088,7 +2084,7 @@ TclCompileDictWithCmd(
     if (gotPath) {
 	Emit14Inst(		INST_LOAD_SCALAR, pathTmp,	envPtr);
     } else {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
     TclEmitOpcode(		INST_DICT_EXPAND,		envPtr);
     Emit14Inst(			INST_STORE_SCALAR, keysTmp,	envPtr);
@@ -2119,7 +2115,7 @@ TclCompileDictWithCmd(
     if (gotPath) {
 	Emit14Inst(		INST_LOAD_SCALAR, pathTmp,	envPtr);
     } else {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
     Emit14Inst(			INST_LOAD_SCALAR, keysTmp,	envPtr);
     if (dictVar == -1) {
@@ -2143,7 +2139,7 @@ TclCompileDictWithCmd(
     if (parsePtr->numWords > 3) {
 	Emit14Inst(		INST_LOAD_SCALAR, pathTmp,	envPtr);
     } else {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
     Emit14Inst(			INST_LOAD_SCALAR, keysTmp,	envPtr);
     if (dictVar == -1) {
@@ -2265,7 +2261,7 @@ TclCompileErrorCmd(
     }
     messageTokenPtr = TokenAfter(parsePtr->tokenPtr);
 
-    PushLiteral(envPtr, "-code error -level 0", 20);
+    PushStringLiteral(envPtr, "-code error -level 0");
     CompileWord(envPtr, messageTokenPtr, interp, 1);
     TclEmitOpcode(INST_RETURN_STK, envPtr);
     envPtr->currStackDepth = savedStackDepth + 1;
@@ -2478,7 +2474,7 @@ TclCompileForCmd(
      */
 
     envPtr->currStackDepth = savedStackDepth;
-    PushLiteral(envPtr, "", 0);
+    PushStringLiteral(envPtr, "");
 
     return TCL_OK;
 }
@@ -2788,7 +2784,7 @@ CompileEachloopCmd(
      */
      
     if (collect == TCL_EACH_COLLECT) {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	Emit14Inst(		INST_STORE_SCALAR, collectVar,	envPtr);
 	TclEmitOpcode(		INST_POP,			envPtr);
     }
@@ -2881,7 +2877,7 @@ CompileEachloopCmd(
 	TclEmitInstInt1(INST_UNSET_SCALAR, 0,			envPtr);
 	TclEmitInt4(		collectVar,			envPtr);
     } else {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
     envPtr->currStackDepth = savedStackDepth + 1;
 
@@ -3253,7 +3249,7 @@ TclCompileFormatCmd(
 	 */
 
 	TclEmitOpcode(INST_DUP, envPtr);
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	TclEmitOpcode(INST_STR_EQ, envPtr);
 	TclEmitOpcode(INST_POP, envPtr);
     }
@@ -3476,7 +3472,7 @@ TclPushVarName(
 		TclCompileTokens(interp, elemTokenPtr, elemTokenCount,
 			envPtr);
 	    } else {
-		PushLiteral(envPtr, "", 0);
+		PushStringLiteral(envPtr, "");
 	    }
 	}
     } else {
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
index 2bd43b6..13b874e 100644
--- a/generic/tclCompCmdsGR.c
+++ b/generic/tclCompCmdsGR.c
@@ -77,7 +77,7 @@ TclCompileGlobalCmd(
      * Push the namespace
      */
 
-    PushLiteral(envPtr, "::", 2);
+    PushStringLiteral(envPtr, "::");
 
     /*
      * Loop over the variables.
@@ -100,7 +100,7 @@ TclCompileGlobalCmd(
      */
 
     TclEmitOpcode(		INST_POP,			envPtr);
-    PushLiteral(envPtr, "", 0);
+    PushStringLiteral(envPtr, "");
     return TCL_OK;
 }
 
@@ -376,7 +376,7 @@ TclCompileIfCmd(
 	 */
 
 	if (compileScripts) {
-	    PushLiteral(envPtr, "", 0);
+	    PushStringLiteral(envPtr, "");
 	}
     }
 
@@ -1203,7 +1203,7 @@ TclCompileListCmd(
 	 * [list] without arguments just pushes an empty object.
 	 */
 
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
 	return TCL_OK;
     }
 
@@ -1545,7 +1545,7 @@ TclCompileLreplaceCmd(
     if (guaranteedDropAll) {
 	TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
 	TclEmitOpcode(		INST_POP,			envPtr);
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     } else {
 	TclEmitInstInt4(	INST_LIST_RANGE_IMM, idx1,	envPtr);
 	TclEmitInt4(		idx2,				envPtr);
@@ -1811,8 +1811,8 @@ TclCompileNamespaceCodeCmd(
      * the value needs to be determined at runtime for safety.
      */
 
-    PushLiteral(envPtr,		"::namespace",		11);
-    PushLiteral(envPtr,		"inscope",		7);
+    PushStringLiteral(envPtr,		"::namespace");
+    PushStringLiteral(envPtr,		"inscope");
     TclEmitOpcode(		INST_NS_CURRENT,	envPtr);
     CompileWord(envPtr,		tokenPtr,		interp, 1);
     TclEmitInstInt4(		INST_LIST, 4,		envPtr);
@@ -1837,17 +1837,17 @@ TclCompileNamespaceQualifiersCmd(
     }
 
     CompileWord(envPtr, tokenPtr, interp, 1);
-    PushLiteral(envPtr, "0", 1);
-    PushLiteral(envPtr, "::", 2);
+    PushStringLiteral(envPtr, "0");
+    PushStringLiteral(envPtr, "::");
     TclEmitInstInt4(	INST_OVER, 2,			envPtr);
     TclEmitOpcode(	INST_STR_FIND_LAST,		envPtr);
     off = CurrentOffset(envPtr);
-    PushLiteral(envPtr, "1", 1);
+    PushStringLiteral(envPtr, "1");
     TclEmitOpcode(	INST_SUB,			envPtr);
     TclEmitInstInt4(	INST_OVER, 2,			envPtr);
     TclEmitInstInt4(	INST_OVER, 1,			envPtr);
     TclEmitOpcode(	INST_STR_INDEX,			envPtr);
-    PushLiteral(envPtr, ":", 1);
+    PushStringLiteral(envPtr, ":");
     TclEmitOpcode(	INST_STR_EQ,			envPtr);
     off = off - CurrentOffset(envPtr);
     TclEmitInstInt1(	INST_JUMP_TRUE1, off,		envPtr);
@@ -1877,17 +1877,17 @@ TclCompileNamespaceTailCmd(
      */
 
     CompileWord(envPtr, tokenPtr, interp, 1);
-    PushLiteral(envPtr, "::", 2);
+    PushStringLiteral(envPtr, "::");
     TclEmitInstInt4(	INST_OVER, 1,			envPtr);
     TclEmitOpcode(	INST_STR_FIND_LAST,		envPtr);
     TclEmitOpcode(	INST_DUP,			envPtr);
-    PushLiteral(envPtr, "0", 1);
+    PushStringLiteral(envPtr, "0");
     TclEmitOpcode(	INST_GE,			envPtr);
     TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFixup);
-    PushLiteral(envPtr, "2", 1);
+    PushStringLiteral(envPtr, "2");
     TclEmitOpcode(	INST_ADD,			envPtr);
     TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127);
-    PushLiteral(envPtr, "end", 3);
+    PushStringLiteral(envPtr, "end");
     TclEmitOpcode(	INST_STR_RANGE,			envPtr);
     return TCL_OK;
 }
@@ -1951,7 +1951,7 @@ TclCompileNamespaceUpvarCmd(
      */
 
     TclEmitOpcode(		INST_POP,			envPtr);
-    PushLiteral(envPtr, "", 0);
+    PushStringLiteral(envPtr, "");
     return TCL_OK;
 }
 
@@ -2117,7 +2117,7 @@ TclCompileRegexpCmd(
 	     * The semantics of regexp are always match on re == "".
 	     */
 
-	    PushLiteral(envPtr, "1", 1);
+	    PushStringLiteral(envPtr, "1");
 	    return TCL_OK;
 	}
 
@@ -2459,7 +2459,7 @@ TclCompileReturnCmd(
 	 * No explict result argument, so default result is empty string.
 	 */
 
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
 
     /*
@@ -2534,7 +2534,7 @@ TclCompileReturnCmd(
     if (explicitResult) {
 	CompileWord(envPtr, wordTokenPtr, interp, numWords-1);
     } else {
-	PushLiteral(envPtr, "", 0);
+	PushStringLiteral(envPtr, "");
     }
 
     /*
@@ -2646,7 +2646,7 @@ TclCompileUpvarCmd(
 	    if (!(numWords%2)) {
 		return TCL_ERROR;
 	    }
-	    PushLiteral(envPtr, "1", 1);
+	    PushStringLiteral(envPtr, "1");
 	    otherTokenPtr = tokenPtr;
 	    i = 3;
 	}
@@ -2679,7 +2679,7 @@ TclCompileUpvarCmd(
      */
 
     TclEmitOpcode(		INST_POP,			envPtr);
-    PushLiteral(envPtr, "", 0);
+    PushStringLiteral(envPtr, "");
     return TCL_OK;
 }
 
@@ -2760,7 +2760,7 @@ TclCompileVariableCmd(
      * Set the result to empty
      */
 
-    PushLiteral(envPtr, "", 0);
+    PushStringLiteral(envPtr, "");
     return TCL_OK;
 }
 
diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c
index 4a7d45b..7ce51b6 100644
--- a/generic/tclCompCmdsSZ.c
+++ b/generic/tclCompCmdsSZ.c
@@ -88,7 +88,7 @@ const AuxDataType tclJumptableInfoType = {
 #define BODY(token,index) \
     SetLineInformation((index));CompileBody(envPtr,(token),interp)
 #define PUSH(str) \
-    PushLiteral(envPtr,(str),strlen(str))
+    PushStringLiteral(envPtr, str)
 #define JUMP(var,name) \
     (var) = CurrentOffset(envPtr);TclEmitInstInt4(INST_##name,0,envPtr)
 #define FIXJUMP(var) \
@@ -757,7 +757,7 @@ TclSubstCompile(
 
     tokenPtr = parse.tokenPtr;
     if (tokenPtr->type != TCL_TOKEN_TEXT && tokenPtr->type != TCL_TOKEN_BS) {
-	PushLiteral(envPtr, "", 0);
+	PUSH("");
 	count++;
     }
 
@@ -1420,7 +1420,7 @@ IssueSwitchChainedTests(
 			 * when the RE == "".
 			 */
 
-			PushLiteral(envPtr, "1", 1);
+			PUSH("1");
 			break;
 		    }
 
@@ -1545,7 +1545,7 @@ IssueSwitchChainedTests(
 
     if (!foundDefault) {
 	OP(	POP);
-	PushLiteral(envPtr, "", 0);
+	PUSH("");
     }
 
     /*
@@ -1764,7 +1764,7 @@ IssueSwitchJumpTable(
 	envPtr->currStackDepth = savedStackDepth;
 	TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
 		envPtr->codeStart+jumpToDefault+1);
-	PushLiteral(envPtr, "", 0);
+	PUSH("");
     }
 
     /*
@@ -2338,10 +2338,11 @@ IssueTryInstructions(
     for (i=0 ; i<numHandlers ; i++) {
 	sprintf(buf, "%d", matchCodes[i]);
 	OP(				DUP);
-	PUSH(				buf);
+	PushLiteral(envPtr, buf, strlen(buf));
 	OP(				EQ);
 	JUMP(notCodeJumpSource,		JUMP_FALSE4);
 	if (matchClauses[i]) {
+	    const char *p;
 	    Tcl_ListObjLength(NULL, matchClauses[i], &len);
 
 	    /*
@@ -2353,7 +2354,8 @@ IssueTryInstructions(
 	    OP4(			DICT_GET, 1);
 	    TclAdjustStackDepth(-1, envPtr);
 	    OP44(			LIST_RANGE_IMM, 0, len-1);
-	    PUSH(			TclGetString(matchClauses[i]));
+	    p = Tcl_GetStringFromObj(matchClauses[i], &len);
+	    PushLiteral(envPtr, p, len);
 	    OP(				STR_EQ);
 	    JUMP(notECJumpSource,	JUMP_FALSE4);
 	} else {
@@ -2493,10 +2495,11 @@ IssueTryFinallyInstructions(
 	for (i=0 ; i<numHandlers ; i++) {
 	    sprintf(buf, "%d", matchCodes[i]);
 	    OP(				DUP);
-	    PUSH(			buf);
+	    PushLiteral(envPtr,	buf, strlen(buf));
 	    OP(				EQ);
 	    JUMP(notCodeJumpSource,	JUMP_FALSE4);
 	    if (matchClauses[i]) {
+		const char *p;
 		Tcl_ListObjLength(NULL, matchClauses[i], &len);
 
 		/*
@@ -2508,7 +2511,8 @@ IssueTryFinallyInstructions(
 		OP4(			DICT_GET, 1);
 		TclAdjustStackDepth(-1, envPtr);
 		OP44(			LIST_RANGE_IMM, 0, len-1);
-		PUSH(			TclGetString(matchClauses[i]));
+		p = Tcl_GetStringFromObj(matchClauses[i], &len);
+		PushLiteral(envPtr, p, len);
 		OP(			STR_EQ);
 		JUMP(notECJumpSource,	JUMP_FALSE4);
 	    } else {
@@ -2744,7 +2748,7 @@ TclCompileUnsetCmd(
 
 	varTokenPtr = TokenAfter(varTokenPtr);
     }
-    PushLiteral(envPtr, "", 0);
+    PUSH("");
     return TCL_OK;
 }
 
@@ -2923,7 +2927,7 @@ TclCompileWhileCmd(
 
   pushResult:
     envPtr->currStackDepth = savedStackDepth;
-    PushLiteral(envPtr, "", 0);
+    PUSH("");
     return TCL_OK;
 }
 
@@ -2959,7 +2963,7 @@ TclCompileYieldCmd(
     }
 
     if (parsePtr->numWords == 1) {
-	PushLiteral(envPtr, "", 0);
+	PUSH("");
     } else {
 	DefineLineInformation;	/* TIP #280 */
 	Tcl_Token *valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
@@ -3125,7 +3129,7 @@ CompileComparisonOpCmd(
     DefineLineInformation;	/* TIP #280 */
 
     if (parsePtr->numWords < 3) {
-	PushLiteral(envPtr, "1", 1);
+	PUSH("1");
     } else if (parsePtr->numWords == 3) {
 	tokenPtr = TokenAfter(parsePtr->tokenPtr);
 	CompileWord(envPtr, tokenPtr, interp, 1);
@@ -3296,7 +3300,7 @@ TclCompilePowOpCmd(
 	CompileWord(envPtr, tokenPtr, interp, words);
     }
     if (parsePtr->numWords <= 2) {
-	PushLiteral(envPtr, "1", 1);
+	PUSH("1");
 	words++;
     }
     while (--words > 1) {
@@ -3514,7 +3518,7 @@ TclCompileDivOpCmd(
 	return TCL_ERROR;
     }
     if (parsePtr->numWords == 2) {
-	PushLiteral(envPtr, "1.0", 3);
+	PUSH("1.0");
     }
     for (words=1 ; words<parsePtr->numWords ; words++) {
 	tokenPtr = TokenAfter(tokenPtr);
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index 1cc296e..3909fa9 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -1358,15 +1358,19 @@ MODULE_SCOPE Tcl_Obj	*TclNewInstNameObj(unsigned char inst);
     TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
 	    (envPtr));
 /*
- * Convenience macro for use when pushing literals. The ANSI C "prototype" for
- * this macro is:
+ * Convenience macros for use when pushing literals. The ANSI C "prototype" for
+ * these macros are:
  *
  * static void		PushLiteral(CompileEnv *envPtr,
  *			    const char *string, int length);
+ * static void		PushStringLiteral(CompileEnv *envPtr,
+ *			    const char *string);
  */
 
 #define PushLiteral(envPtr, string, length) \
     TclEmitPush(TclRegisterNewLiteral((envPtr), (string), (length)), (envPtr))
+#define PushStringLiteral(envPtr, string) \
+    PushLiteral((envPtr), (string), (int) (sizeof(string "") - 1))
 
 /*
  * Macro to advance to the next token; it is more mnemonic than the address
-- 
cgit v0.12