Tcl Source Code

Check-in [15f9b0abea]
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:More aggressive constant folding in [string cat]. Thanks AndreasK for kicking.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-429
Files: files | file ages | folders
SHA1: 15f9b0abea587e826c4b0b4e427dc911e820cf23
User & Date: ferrieux 2014-08-05 18:20:48
Context
2014-08-05
22:10
Fix comment inaccuracy. check-in: 7dad8a3e54 user: ferrieux tags: tip-429
18:20
More aggressive constant folding in [string cat]. Thanks AndreasK for kicking. check-in: 15f9b0abea user: ferrieux tags: tip-429
11:29
Better organize [string cat] by chunks of 255 args. check-in: 97af63ba9c user: ferrieux tags: tip-429
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclCompCmdsSZ.c.

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
    /* 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) */

    numArgs = 0;
    wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
    for (i = 1; i < numWords; i++) {
	CompileWord(envPtr, wordTokenPtr, interp, i);

	numArgs ++;
	if (numArgs == 255) {
	    TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
	    numArgs = 1;	/* concat pushes 1 obj, the result */
	}
	wordTokenPtr = TokenAfter(wordTokenPtr);
    }
    if (numArgs > 1) {
	TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
    }

    return TCL_OK;
}






|
>

>
|




>
|
>
|
>
>
>

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








|
<
<
<
<
<
<
<
<
>

<
<
<
<
<







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
338
339
340
341
    /* Trivial case, no arg */

    if (numWords<2) {
	PushStringLiteral(envPtr, "");
	return TCL_OK;
    }
	
    /* General case: issue CONCAT1's (by chunks of 255 if needed), folding
       contiguous constants along the way */

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

		numArgs ++;
	    }
	    CompileWord(envPtr, wordTokenPtr, interp, i);
	    numArgs ++;
	    if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */
		TclEmitInstInt1(INST_STR_CONCAT1, 254, envPtr);
		numArgs -= 253;	/* concat pushes 1 obj, the result */
	    }
	}
	wordTokenPtr = TokenAfter(wordTokenPtr);
    }
    if (folded) {
	int len;
	const char *bytes = Tcl_GetStringFromObj(folded, &len);
	
	PushLiteral(envPtr, bytes, len);
	Tcl_DecrRefCount(folded);








	folded = NULL;
	numArgs ++;





    }
    if (numArgs > 1) {
	TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
    }

    return TCL_OK;
}