Tcl Source Code

Check-in [a321e41d54]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Add constant folding to [string cat]. Mixed-quote idiom is now compiled to a single push.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-429
Files: files | file ages | folders
SHA1: a321e41d540908f3ad060c842ae592e238a21a82
User & Date: ferrieux 2014-08-05 10:34:10
Context
2014-08-05
11:29
Better organize [string cat] by chunks of 255 args. check-in: 97af63ba9c user: ferrieux tags: tip-429
10:34
Add constant folding to [string cat]. Mixed-quote idiom is now compiled to a single push. check-in: a321e41d54 user: ferrieux tags: tip-429
09:55
More optimized non-BC [string cat] using Tcl_AppendObjToObj() - thx Donal check-in: 70c49b9302 user: ferrieux tags: tip-429
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclCompCmdsSZ.c.

273
274
275
276
277
278
279
280
281

282
283


284





















285

286







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
				 * created by Tcl_ParseCommand. */
    Command *cmdPtr,		/* Points to defintion of command being
				 * compiled. */
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    int numWords = parsePtr->numWords;
    Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr);

    DefineLineInformation;	/* TIP #280 */



    if (numWords>=2) {





















	int i;









	for (i = 1; i < numWords; i++) {
	    CompileWord(envPtr, wordTokenPtr, interp, i);
	    wordTokenPtr = TokenAfter(wordTokenPtr);
	}
	while (numWords > 256) {
	    TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
	    numWords -= 254;	/* concat pushes 1 obj, the result */
	}
	if (numWords > 2) {
	    TclEmitInstInt1(INST_STR_CONCAT1, numWords - 1, envPtr);
	}
    } else {
	PushStringLiteral(envPtr, "");
    }
    return TCL_OK;
}

int
TclCompileStringCmpCmd(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command






|
|
>


>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
<
<
|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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
333
334
335
336
337
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
				 * created by Tcl_ParseCommand. */
    Command *cmdPtr,		/* Points to defintion of command being
				 * compiled. */
    CompileEnv *envPtr)		/* Holds resulting instructions. */
{
    int i,numWords = parsePtr->numWords;
    Tcl_Token *wordTokenPtr;
    Tcl_Obj *obj, *folded;
    DefineLineInformation;	/* TIP #280 */

    /* Trivial case, no arg */

    if (numWords<2) {
	PushStringLiteral(envPtr, "");
	return TCL_OK;
    }
	
    /* Detection of foldable constants. Often used for mixed quoting. */

    folded = Tcl_NewObj();
    wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
    for (i = 1; i < numWords; i++) {
	obj = Tcl_NewObj();
	if (TclWordKnownAtCompileTime(wordTokenPtr, obj)) {
	    Tcl_AppendObjToObj(folded, obj);
	} else {
	    Tcl_DecrRefCount(obj);
	    Tcl_DecrRefCount(folded);
	    folded = NULL;
	    break;
	}
	wordTokenPtr = TokenAfter(wordTokenPtr);
    }
    if (folded) {
	int len;
	const char *bytes = Tcl_GetStringFromObj(folded, &len);
	
	PushLiteral(envPtr, bytes, len);
	return TCL_OK;
    }

    /* General case: just issue CONCAT1's (by chunks of 255 if needed) */

    wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
    for (i = 1; i < numWords; i++) {
	CompileWord(envPtr, wordTokenPtr, interp, i);
	wordTokenPtr = TokenAfter(wordTokenPtr);
    }
    while (numWords > 256) {
	TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
	numWords -= 254;	/* concat pushes 1 obj, the result */
    }
    if (numWords > 2) {
	TclEmitInstInt1(INST_STR_CONCAT1, numWords - 1, envPtr);
    }



    return TCL_OK;
}

int
TclCompileStringCmpCmd(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command