Tcl Source Code

Check-in [0208fd3481]
Login

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

Overview
Comment:merge trunk
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | mig-review
Files: files | file ages | folders
SHA1: 0208fd348138d4cb369cce7ed26979d293543c54
User & Date: dgp 2013-06-05 11:59:30.397
Context
2013-06-05
15:24
merge trunk

Fossil has hopelessly fouled up this checkin's branch history. Closed-Leaf check-in: 53494f969b user: dgp tags: mig-review

11:59
merge trunk check-in: 0208fd3481 user: dgp tags: mig-review
08:11
[Bugs 2835313, 3614226]: Complete the construction of break/continue compilers that get the stack cl... check-in: ac84c44dcf user: dkf tags: bug-3614342
2013-06-03
22:43
repair error.test check-in: 59081017e1 user: dgp tags: mig-review
Changes
Unified Diff Show Whitespace Changes Patch
Changes to ChangeLog.















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29















2013-06-03  Miguel Sofer  <[email protected]>

	* generic/tclExecute.c: fix for perf bug detected by Kieran
	(https://groups.google.com/forum/?fromgroups#!topic/comp.lang.tcl/vfpI3bc-DkQ),
	diagnosed by dgp to be a close relative of [Bug 781585], which was
	fixed by commit	[f46fb50cb3]. This bug was introduced by myself in
	commit [cbfe055d8c]. 

2013-06-03  Donal K. Fellows  <[email protected]>

	* generic/tclCompCmds.c (TclCompileBreakCmd, TclCompileContinueCmd):
	Added code to allow [break] and [continue] to be issued as a jump (in
	the most common cases) rather than using the more expensive exception
	processing path in the bytecode engine. [Bug 3614226]: Partial fix for
	the issues relating to cleaning up the stack when dealing with [break]
	and [continue].

2013-05-27 Harald Oehlmann  <[email protected]>

	* library/msgcat/msgcat.tcl: [Bug 3036566]: Also get locale from
	registry key HCU\Control Panel\Desktop : PreferredUILanguages to
	honor installed language packs on Vista+.
	Bumped msgcat version to 1.5.2

2013-05-22  Andreas Kupries  <[email protected]>

	* tclCompile.c: Removed duplicate const qualifier causing the HP
	  native cc to error out.

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2013-06-05  Donal K. Fellows  <[email protected]>

	* generic/tclExecute.c (INST_EXPAND_DROP): [Bugs 2835313, 3614226]:
	New opcode to allow resetting the stack to get rid of an expansion,
	restoring the stack to a known state in the process.
	* generic/tclCompile.c, generic/tclCompCmds.c: Adjusted the compilers
	for [break] and [continue] to get stack cleanup right in the majority
	of cases.
	* tests/for.test (for-7.*): Set of tests for these evil cases.

2013-06-04  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: Eliminate NO_VIZ macro as current zlib uses HAVE_HIDDEN
	instead. One more last-moment fix for FreeBSD by Pietro Cerutti

2013-06-03  Miguel Sofer  <[email protected]>

	* generic/tclExecute.c: fix for perf bug detected by Kieran
	(https://groups.google.com/forum/?fromgroups#!topic/comp.lang.tcl/vfpI3bc-DkQ),
	diagnosed by dgp to be a close relative of [Bug 781585], which was
	fixed by commit	[f46fb50cb3]. This bug was introduced by myself in
	commit [cbfe055d8c]. 

2013-06-03  Donal K. Fellows  <[email protected]>

	* generic/tclCompCmds.c (TclCompileBreakCmd, TclCompileContinueCmd):
	Added code to allow [break] and [continue] to be issued as a jump (in
	the most common cases) rather than using the more expensive exception
	processing path in the bytecode engine. [Bug 3614226]: Partial fix for
	the issues relating to cleaning up the stack when dealing with [break]
	and [continue].

2013-05-27 Harald Oehlmann  <[email protected]>

	* library/msgcat/msgcat.tcl: [Bug 3036566]: Also get locale from
	registry key HCU\Control Panel\Desktop : PreferredUILanguages to honor
	installed language packs on Vista+.
	Bumped msgcat version to 1.5.2

2013-05-22  Andreas Kupries  <[email protected]>

	* tclCompile.c: Removed duplicate const qualifier causing the HP
	  native cc to error out.

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	need for various wrapper functions/macros. For Tcl 9 a better
	solution is needed, but that cannot be done without introducing
	binary incompatibility.

2013-04-30  Andreas Kupries  <[email protected]>

	* library/platform/platform.tcl (::platform::LibcVersion):
	* library/platform/pkgIndex.tcl: Followup to the 2013-01-30
	  change. The RE become too restrictive again. SuSe added a
	  timestamp after the version. Loosened up a bit. Bumped package
	  to version 1.0.12.

2013-04-29  Donal K. Fellows  <[email protected]>

	* generic/tclCompCmds.c (TclCompileArraySetCmd): Generate better code
	when the list of things to set is a literal.

2013-04-25  Jan Nijtmans  <[email protected]>

	* generic/tclDecls.h: Implement Tcl_NewBooleanObj, Tcl_DbNewBooleanObj
	and Tcl_SetBooleanObj as macros using Tcl_NewIntObj, Tcl_DbNewLongObj
	and Tcl_SetIntObj. Starting with Tcl 8.5, this is exactly the same,
	it only eliminates code duplication.
	* generic/tclInt.h: Eliminate use of NO_WIDE_TYPE everywhere: It's
	exactly the same as TCL_WIDE_INT_IS_LONG

2013-04-19  Jan Nijtmans  <[email protected]>

	* generic/tclDecls.h: Implement many Tcl_*Var* functions and
	Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp
	their Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct.

2013-04-12  Jan Nijtmans  <[email protected]>

	* generic/tclDecls.h: Implement Tcl_Pkg* functions as
	(faster/stack-saving) macros around Tcl_Pkg*Ex functions.

2013-04-08  Don Porter  <[email protected]>

	* generic/regc_color.c:	[Bug 3610026] Stop crash when the number of
	* generic/regerrs.h:	"colors" in a regular expression overflows
	* generic/regex.h:	a short int.  Thanks to Heikki Linnakangas
	* generic/regguts.h:	for the report and the patch.
	* tests/regexp.test:

2013-04-04  Reinhard Max  <[email protected]>

	* library/http/http.tcl (http::geturl): Allow URLs that don't have
	a path, but a query query, e.g. http://example.com?foo=bar .
	* Bump the http package to 2.8.7.

2013-03-22  Venkat Iyer <[email protected]>
	* library/tzdata/Africa/Cairo: Update to tzdata2013b.
	* library/tzdata/Africa/Casablanca:
	* library/tzdata/Africa/Gaborone:
	* library/tzdata/Africa/Tripoli:







|
|
|
<


















|
|








|
|
|
|




|
|







98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
	need for various wrapper functions/macros. For Tcl 9 a better
	solution is needed, but that cannot be done without introducing
	binary incompatibility.

2013-04-30  Andreas Kupries  <[email protected]>

	* library/platform/platform.tcl (::platform::LibcVersion):
	* library/platform/pkgIndex.tcl: Followup to the 2013-01-30 change.
	The RE become too restrictive again. SuSe added a timestamp after the
	version. Loosened up a bit. Bumped package to version 1.0.12.


2013-04-29  Donal K. Fellows  <[email protected]>

	* generic/tclCompCmds.c (TclCompileArraySetCmd): Generate better code
	when the list of things to set is a literal.

2013-04-25  Jan Nijtmans  <[email protected]>

	* generic/tclDecls.h: Implement Tcl_NewBooleanObj, Tcl_DbNewBooleanObj
	and Tcl_SetBooleanObj as macros using Tcl_NewIntObj, Tcl_DbNewLongObj
	and Tcl_SetIntObj. Starting with Tcl 8.5, this is exactly the same,
	it only eliminates code duplication.
	* generic/tclInt.h: Eliminate use of NO_WIDE_TYPE everywhere: It's
	exactly the same as TCL_WIDE_INT_IS_LONG

2013-04-19  Jan Nijtmans  <[email protected]>

	* generic/tclDecls.h: Implement many Tcl_*Var* functions and
	Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp their
	Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct.

2013-04-12  Jan Nijtmans  <[email protected]>

	* generic/tclDecls.h: Implement Tcl_Pkg* functions as
	(faster/stack-saving) macros around Tcl_Pkg*Ex functions.

2013-04-08  Don Porter  <[email protected]>

	* generic/regc_color.c:	[Bug 3610026]: Stop crash when the number of
	* generic/regerrs.h:	"colors" in a regular expression overflows a
	* generic/regex.h:	short int.  Thanks to Heikki Linnakangas for
	* generic/regguts.h:	the report and the patch.
	* tests/regexp.test:

2013-04-04  Reinhard Max  <[email protected]>

	* library/http/http.tcl (http::geturl): Allow URLs that don't have a
	path, but a query query, e.g. http://example.com?foo=bar
	* Bump the http package to 2.8.7.

2013-03-22  Venkat Iyer <[email protected]>
	* library/tzdata/Africa/Cairo: Update to tzdata2013b.
	* library/tzdata/Africa/Casablanca:
	* library/tzdata/Africa/Gaborone:
	* library/tzdata/Africa/Tripoli:
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
	* library/tzdata/Pacific/Fiji:
	* library/tzdata/Asia/Khandyga: (new)
	* library/tzdata/Asia/Ust-Nera: (new)
	* library/tzdata/Europe/Busingen: (new)

2013-03-21  Don Porter  <[email protected]>

	* library/auto.tcl: [Bug 2102614] Add ensemble indexing support
	* tests/autoMkindex.test: to [auto_mkindex].  Thanks Brian Griffin.

2013-03-19  Don Porter  <[email protected]>

	* generic/tclFCmd.c: [Bug 3597000] Consistent [file copy] result.
	* tests/fileSystem.test:

2013-03-19  Jan Nijtmans  <[email protected]>

	* win/tclWinFile.c: [Bug 3608360]: Incompatible behaviour of "file
	exists".

2013-03-18  Donal K. Fellows  <[email protected]>

	* tests/cmdAH.test (cmdAH-19.12): [Bug 3608360]: Added test to ensure
	that we never ever allow [file exists] to do globbing.

2013-03-12  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: Patch by Andrew Shadura, providing better support for
	three architectures they have in Debian.

2013-03-11  Don Porter  <[email protected]>

	* generic/tclCompile.c:	[Bugs 3607246,3607372] Unbalanced refcounts
	* generic/tclLiteral.c:	of literals in the global literal table.

2013-03-06  Don Porter  <[email protected]>

	* generic/regc_nfa.c:	[Bugs 3604074,3606683] Rewrite of the
	* generic/regcomp.c:	fixempties() routine (and supporting
	routines) to completely eliminate the infinite loop hazard.
	Thanks to Tom Lane for the much improved solution.

2013-02-28  Don Porter  <[email protected]>

	* generic/tclLiteral.c:	Revise TclReleaseLiteral() to tolerate a
	NULL interp argument.

	* generic/tclCompile.c:	Update callers and revise mistaken comments.
	* generic/tclProc.c:

2013-02-27  Jan Nijtmans  <[email protected]>

	* generic/regcomp.c:	[Bug 3606139]: missing error check allows







|
|



|



















|




|
|
|
|



|
|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	* library/tzdata/Pacific/Fiji:
	* library/tzdata/Asia/Khandyga: (new)
	* library/tzdata/Asia/Ust-Nera: (new)
	* library/tzdata/Europe/Busingen: (new)

2013-03-21  Don Porter  <[email protected]>

	* library/auto.tcl: [Bug 2102614]: Add ensemble indexing support to
	* tests/autoMkindex.test: [auto_mkindex].  Thanks Brian Griffin.

2013-03-19  Don Porter  <[email protected]>

	* generic/tclFCmd.c: [Bug 3597000]: Consistent [file copy] result.
	* tests/fileSystem.test:

2013-03-19  Jan Nijtmans  <[email protected]>

	* win/tclWinFile.c: [Bug 3608360]: Incompatible behaviour of "file
	exists".

2013-03-18  Donal K. Fellows  <[email protected]>

	* tests/cmdAH.test (cmdAH-19.12): [Bug 3608360]: Added test to ensure
	that we never ever allow [file exists] to do globbing.

2013-03-12  Jan Nijtmans  <[email protected]>

	* unix/tcl.m4: Patch by Andrew Shadura, providing better support for
	three architectures they have in Debian.

2013-03-11  Don Porter  <[email protected]>

	* generic/tclCompile.c:	[Bugs 3607246,3607372]: Unbalanced refcounts
	* generic/tclLiteral.c:	of literals in the global literal table.

2013-03-06  Don Porter  <[email protected]>

	* generic/regc_nfa.c:	[Bugs 3604074,3606683]: Rewrite of the
	* generic/regcomp.c:	fixempties() routine (and supporting routines)
	to completely eliminate the infinite loop hazard. Thanks to Tom Lane
	for the much improved solution.

2013-02-28  Don Porter  <[email protected]>

	* generic/tclLiteral.c:	Revise TclReleaseLiteral() to tolerate a NULL
	interp argument.

	* generic/tclCompile.c:	Update callers and revise mistaken comments.
	* generic/tclProc.c:

2013-02-27  Jan Nijtmans  <[email protected]>

	* generic/regcomp.c:	[Bug 3606139]: missing error check allows
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
	normalized paths, otherwise it might result in a crash on CYGWIN.
	Restyle according to the Tcl style guide.
	* generic/tclStrToD.c: [Bug 3005233]: Fix for build on OpenBSD vax

2010-05-19  Alexandre Ferrieux  <[email protected]>

	* tests/dict.test: Add missing tests for [Bug 3004007], fixed under
	                   the radar on 2010-02-24 (dkf): EIAS violation in
	                   list-dict conversions.

2010-05-19  Jan Nijtmans  <[email protected]>

	* generic/regcomp.c:     Don't use arrays of length 1, just use a
	* generic/tclFileName.c: single element then, it makes code more
	* generic/tclLoad.c:     readable. (Here it even prevents a type cast)








|
<







4903
4904
4905
4906
4907
4908
4909
4910

4911
4912
4913
4914
4915
4916
4917
	normalized paths, otherwise it might result in a crash on CYGWIN.
	Restyle according to the Tcl style guide.
	* generic/tclStrToD.c: [Bug 3005233]: Fix for build on OpenBSD vax

2010-05-19  Alexandre Ferrieux  <[email protected]>

	* tests/dict.test: Add missing tests for [Bug 3004007], fixed under
	the radar on 2010-02-24 (dkf): EIAS violation in list-dict conversions


2010-05-19  Jan Nijtmans  <[email protected]>

	* generic/regcomp.c:     Don't use arrays of length 1, just use a
	* generic/tclFileName.c: single element then, it makes code more
	* generic/tclLoad.c:     readable. (Here it even prevents a type cast)

6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
	* tests/http.test
	* library/http/pkgIndex.tcl:  Bump to http 2.8.2
	* unix/Makefile.in:
	* win/Makefile.in:

2009-11-11  Alexandre Ferrieux  <[email protected]>

	* generic/tclIO.c: Fix [Bug 2888099] (close discards ENOSPC error)
	                   by saving the errno from the first of two
	                   FlushChannel()s. Uneasy to test; might need
	                   specific channel drivers. Four-hands with aku.

2009-11-10  Pat Thoyts  <[email protected]>

	* tests/winFCmd.test: Cleanup directories that have been set chmod
	000. On Windows7 and Vista we really have no access and these were
	getting left behind.
	A few tests were changed to reflect the intent of the test where







|
|
<
|







6757
6758
6759
6760
6761
6762
6763
6764
6765

6766
6767
6768
6769
6770
6771
6772
6773
	* tests/http.test
	* library/http/pkgIndex.tcl:  Bump to http 2.8.2
	* unix/Makefile.in:
	* win/Makefile.in:

2009-11-11  Alexandre Ferrieux  <[email protected]>

	* generic/tclIO.c: Fix [Bug 2888099] (close discards ENOSPC error) by
	saving the errno from the first of two FlushChannel()s. Uneasy to

	test; might need specific channel drivers. Four-hands with aku.

2009-11-10  Pat Thoyts  <[email protected]>

	* tests/winFCmd.test: Cleanup directories that have been set chmod
	000. On Windows7 and Vista we really have no access and these were
	getting left behind.
	A few tests were changed to reflect the intent of the test where
Changes to generic/tclAssembly.c.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*-
 *- THINGS TO DO:
 *- More instructions:
 *-   done - alternate exit point (affects stack and exception range checking)
 *-   break and continue - if exception ranges can be sorted out.
 *-   foreach_start4, foreach_step4
 *-   returnImm, returnStk
 *-   expandStart, expandStkTop, invokeExpanded
 *-   dictFirst, dictNext, dictDone
 *-   dictUpdateStart, dictUpdateEnd
 *-   jumpTable testing
 *-   syntax (?)
 *-   returnCodeBranch
 */








|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*-
 *- THINGS TO DO:
 *- More instructions:
 *-   done - alternate exit point (affects stack and exception range checking)
 *-   break and continue - if exception ranges can be sorted out.
 *-   foreach_start4, foreach_step4
 *-   returnImm, returnStk
 *-   expandStart, expandStkTop, invokeExpanded, expandDrop
 *-   dictFirst, dictNext, dictDone
 *-   dictUpdateStart, dictUpdateEnd
 *-   jumpTable testing
 *-   syntax (?)
 *-   returnCodeBranch
 */

Changes to generic/tclCompCmds.c.
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531

532
533
534
535
536



537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

    /*
     * Find the innermost exception range that contains this command.
     */

    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxPtr);
    if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
	int toPop = envPtr->currStackDepth - auxPtr->stackDepth;

	/*
	 * Pop off the extra stack frames.

	 */

	while (toPop > 0) {
	    TclEmitOpcode(INST_POP, envPtr);
	    TclAdjustStackDepth(1, envPtr);
	    toPop--;
	}

	if (envPtr->expandCount == auxPtr->expandTarget) {
	    /*
	     * Found the target! Also, no built-up expansion stack. No need
	     * for a nasty INST_BREAK here.

	     */

	    TclAddLoopBreakFixup(envPtr, auxPtr);
	    goto done;
	}



    }

    /*
     * Emit a break instruction.
     */

    TclEmitOpcode(INST_BREAK, envPtr);

  done:
    /*
     * Instructions that raise exceptions don't really have to follow the
     * usual stack management rules, but the cleanup code does.
     */

    TclAdjustStackDepth(1, envPtr);
    return TCL_OK;
}







<
<

<
>


<
|
|
<
<
|
<

<
<
>


|
<
<
>
>
>



<
<
<
<
<
<
<







509
510
511
512
513
514
515


516

517
518
519

520
521


522

523


524
525
526
527


528
529
530
531
532
533







534
535
536
537
538
539
540

    /*
     * Find the innermost exception range that contains this command.
     */

    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxPtr);
    if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {


	/*

	 * Found the target! No need for a nasty INST_BREAK here.
	 */


	TclCleanupStackForBreakContinue(envPtr, auxPtr);
	TclAddLoopBreakFixup(envPtr, auxPtr);


    } else {

	    /*


	 * Emit a real break.
	     */

	PushStringLiteral(envPtr, "");


	TclEmitOpcode(INST_DUP, envPtr);
	TclEmitInstInt4(INST_RETURN_IMM, TCL_BREAK, envPtr);
	TclEmitInt4(0, envPtr);
    }

    /*







     * Instructions that raise exceptions don't really have to follow the
     * usual stack management rules, but the cleanup code does.
     */

    TclAdjustStackDepth(1, envPtr);
    return TCL_OK;
}
860
861
862
863
864
865
866
867
868
869
870

871
872
873
874
875
876
877
878
879
880
881
882

883
884
885
886
887



888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
    /*
     * See if we can find a valid continueOffset (i.e., not -1) in the
     * innermost containing exception range.
     */

    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE, &auxPtr);
    if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
	int toPop = envPtr->currStackDepth - auxPtr->stackDepth;

	/*
	 * Pop off the extra stack frames.

	 */

	while (toPop > 0) {
	    TclEmitOpcode(INST_POP, envPtr);
	    TclAdjustStackDepth(1, envPtr);
	    toPop--;
	}

	if (envPtr->expandCount == auxPtr->expandTarget) {
	    /*
	     * Found the target! Also, no built-up expansion stack. No need
	     * for a nasty INST_CONTINUE here.

	     */

	    TclAddLoopContinueFixup(envPtr, auxPtr);
	    goto done;
	}



    }

    /*
     * Emit a continue instruction.
     */

    TclEmitOpcode(INST_CONTINUE, envPtr);

  done:
    /*
     * Instructions that raise exceptions don't really have to follow the
     * usual stack management rules, but the cleanup code does.
     */

    TclAdjustStackDepth(1, envPtr);
    return TCL_OK;
}







<
<

<
>


<
|
|
<
<
|
<

<
<
>


|
<
<
>
>
>



<
<
<
<
<
<
<







847
848
849
850
851
852
853


854

855
856
857

858
859


860

861


862
863
864
865


866
867
868
869
870
871







872
873
874
875
876
877
878
    /*
     * See if we can find a valid continueOffset (i.e., not -1) in the
     * innermost containing exception range.
     */

    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE, &auxPtr);
    if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {


	/*

	 * Found the target! No need for a nasty INST_CONTINUE here.
	 */


	TclCleanupStackForBreakContinue(envPtr, auxPtr);
	TclAddLoopContinueFixup(envPtr, auxPtr);


    } else {

	    /*


	 * Emit a real continue.
	     */

	PushStringLiteral(envPtr, "");


	TclEmitOpcode(INST_DUP, envPtr);
	TclEmitInstInt4(INST_RETURN_IMM, TCL_CONTINUE, envPtr);
	TclEmitInt4(0, envPtr);
    }

    /*







     * Instructions that raise exceptions don't really have to follow the
     * usual stack management rules, but the cleanup code does.
     */

    TclAdjustStackDepth(1, envPtr);
    return TCL_OK;
}
Changes to generic/tclCompile.c.
539
540
541
542
543
544
545




546
547
548
549
550
551
552
	/* Concatenates the two lists at the top of the stack into a single
	 * list and pushes that resulting list onto the stack.
	 * Stack: ... list1 list2 => ... [lconcat list1 list2] */
    {"verify",		 5,	 0,	  1,	{OPERAND_UINT4}},
	/* Verify the predicted stack depth (operand) is true during
	 * bytecode execution. */





    {NULL, 0, 0, 0, {OPERAND_NONE}}
};

/*
 * Prototypes for procedures defined later in this file:
 */








>
>
>
>







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
	/* Concatenates the two lists at the top of the stack into a single
	 * list and pushes that resulting list onto the stack.
	 * Stack: ... list1 list2 => ... [lconcat list1 list2] */
    {"verify",		 5,	 0,	  1,	{OPERAND_UINT4}},
	/* Verify the predicted stack depth (operand) is true during
	 * bytecode execution. */

    {"expandDrop",       1,    0,          0,	{OPERAND_NONE}},
	/* Drops an element from the auxiliary stack, popping stack elements
	 * until the matching stack depth is reached. */

    {NULL, 0, 0, 0, {OPERAND_NONE}}
};

/*
 * Prototypes for procedures defined later in this file:
 */

570
571
572
573
574
575
576

577
578
579
580
581
582
583
static void		PeepholeOptimize(CompileEnv *envPtr);
#ifdef TCL_COMPILE_STATS
static void		RecordByteCodeStats(ByteCode *codePtr);
#endif /* TCL_COMPILE_STATS */
static void		RegisterAuxDataType(const AuxDataType *typePtr);
static int		SetByteCodeFromAny(Tcl_Interp *interp,
			    Tcl_Obj *objPtr);

static int		FormatInstruction(ByteCode *codePtr,
			    const unsigned char *pc, Tcl_Obj *bufferObj);
static void		PrintSourceToObj(Tcl_Obj *appendObj,
			    const char *stringPtr, int maxChars);
static void		UpdateStringOfInstName(Tcl_Obj *objPtr);

/*







>







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
static void		PeepholeOptimize(CompileEnv *envPtr);
#ifdef TCL_COMPILE_STATS
static void		RecordByteCodeStats(ByteCode *codePtr);
#endif /* TCL_COMPILE_STATS */
static void		RegisterAuxDataType(const AuxDataType *typePtr);
static int		SetByteCodeFromAny(Tcl_Interp *interp,
			    Tcl_Obj *objPtr);
static void		StartExpanding(CompileEnv *envPtr);
static int		FormatInstruction(ByteCode *codePtr,
			    const unsigned char *pc, Tcl_Obj *bufferObj);
static void		PrintSourceToObj(Tcl_Obj *appendObj,
			    const char *stringPtr, int maxChars);
static void		UpdateStringOfInstName(Tcl_Obj *objPtr);

/*
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074

	    /*
	     * Should only start issuing instructions after the "command has
	     * started" so that the command range is correct in the bytecode.
	     */

	    if (expand) {
		TclEmitOpcode(INST_EXPAND_START, envPtr);
		envPtr->expandCount++;
	    }

	    /*
	     * TIP #280. Scan the words and compute the extended location
	     * information. The map first contain full per-word line
	     * information for use by the compiler. This is later replaced by
	     * a reduced form which signals non-literal words, stored in







<
|







2064
2065
2066
2067
2068
2069
2070

2071
2072
2073
2074
2075
2076
2077
2078

	    /*
	     * Should only start issuing instructions after the "command has
	     * started" so that the command range is correct in the bytecode.
	     */

	    if (expand) {

		StartExpanding(envPtr);
	    }

	    /*
	     * TIP #280. Scan the words and compute the extended location
	     * information. The map first contain full per-word line
	     * information for use by the compiler. This is later replaced by
	     * a reduced form which signals non-literal words, stored in
3465
3466
3467
3468
3469
3470
3471

3472
3473
3474
3475
3476
3477
3478
    rangePtr->breakOffset = -1;
    rangePtr->continueOffset = -1;
    rangePtr->catchOffset = -1;
    auxPtr = &envPtr->exceptAuxArrayPtr[index];
    auxPtr->supportsContinue = 1;
    auxPtr->stackDepth = envPtr->currStackDepth;
    auxPtr->expandTarget = envPtr->expandCount;

    auxPtr->numBreakTargets = 0;
    auxPtr->breakTargets = NULL;
    auxPtr->allocBreakTargets = 0;
    auxPtr->numContinueTargets = 0;
    auxPtr->continueTargets = NULL;
    auxPtr->allocContinueTargets = 0;
    return index;







>







3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
    rangePtr->breakOffset = -1;
    rangePtr->continueOffset = -1;
    rangePtr->catchOffset = -1;
    auxPtr = &envPtr->exceptAuxArrayPtr[index];
    auxPtr->supportsContinue = 1;
    auxPtr->stackDepth = envPtr->currStackDepth;
    auxPtr->expandTarget = envPtr->expandCount;
    auxPtr->expandTargetDepth = -1;
    auxPtr->numBreakTargets = 0;
    auxPtr->breakTargets = NULL;
    auxPtr->allocBreakTargets = 0;
    auxPtr->numContinueTargets = 0;
    auxPtr->continueTargets = NULL;
    auxPtr->allocContinueTargets = 0;
    return index;
3585
3586
3587
3588
3589
3590
3591

































































































3592
3593
3594
3595
3596
3597
3598
	    CurrentOffset(envPtr);
    TclEmitInstInt4(INST_JUMP4, 0, envPtr);
}

/*
 * ---------------------------------------------------------------------
 *

































































































 * TclFinalizeLoopExceptionRange --
 *
 *	Finalizes a loop exception range, binding the registered [break] and
 *	[continue] implementations so that they jump to the correct place.
 *	Note that this must only be called after *all* the exception range
 *	target offsets have been set.
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
	    CurrentOffset(envPtr);
    TclEmitInstInt4(INST_JUMP4, 0, envPtr);
}

/*
 * ---------------------------------------------------------------------
 *
 * TclCleanupStackForBreakContinue --
 *
 *	Ditch the extra elements from the auxiliary stack and the main
 *	stack. How to do this exactly depends on whether there are any
 *	elements on the auxiliary stack to pop.
 *
 * ---------------------------------------------------------------------
 */

void
TclCleanupStackForBreakContinue(
    CompileEnv *envPtr,
    ExceptionAux *auxPtr)
{
    int toPop = envPtr->expandCount - auxPtr->expandTarget;

    if (toPop > 0) {
	while (toPop > 0) {
	    TclEmitOpcode(INST_EXPAND_DROP, envPtr);
	    toPop--;
	}
	toPop = auxPtr->expandTargetDepth - auxPtr->stackDepth;
	while (toPop > 0) {
	    TclEmitOpcode(INST_POP, envPtr);
	    TclAdjustStackDepth(1, envPtr);
	    toPop--;
	}
    } else {
	toPop = envPtr->currStackDepth - auxPtr->stackDepth;
	while (toPop > 0) {
	    TclEmitOpcode(INST_POP, envPtr);
	    TclAdjustStackDepth(1, envPtr);
	    toPop--;
	}
    }
}

/*
 * ---------------------------------------------------------------------
 *
 * StartExpanding --
 *
 *	Pushes an INST_EXPAND_START and does some additional housekeeping so
 *	that the [break] and [continue] compilers can use an exception-free
 *	issue to discard it.
 *
 * ---------------------------------------------------------------------
 */

static void
StartExpanding(
    CompileEnv *envPtr)
{
    int i;

    TclEmitOpcode(INST_EXPAND_START, envPtr);

    /*
     * Update inner exception ranges with information about the environment
     * where this expansion started.
     */

    for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
	ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
	ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[i];

	/*
	 * Ignore loops unless they're still being built.
	 */

	if (rangePtr->codeOffset > CurrentOffset(envPtr)) {
	    continue;
	}
	if (rangePtr->numCodeBytes != -1) {
	    continue;
	}

	/*
	 * Adequate condition: further out loops and further in exceptions
	 * don't actually need this information.
	 */

	if (auxPtr->expandTarget == envPtr->expandCount) {
	    auxPtr->expandTargetDepth = envPtr->currStackDepth;
	}
    }

    /*
     * There's now one more expansion being processed on the auxiliary stack.
     */

    envPtr->expandCount++;
}

/*
 * ---------------------------------------------------------------------
 *
 * TclFinalizeLoopExceptionRange --
 *
 *	Finalizes a loop exception range, binding the registered [break] and
 *	[continue] implementations so that they jump to the correct place.
 *	Note that this must only be called after *all* the exception range
 *	target offsets have been set.
 *
3625
3626
3627
3628
3629
3630
3631
3632

3633
3634
3635
3636
3637
3638
3639
    }
    for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
	site = envPtr->codeStart + auxPtr->continueTargets[i];
	if (rangePtr->continueOffset == -1) {
	    int j;

	    /*
	     * WTF? Can't bind, so revert to an INST_CONTINUE.

	     */

	    *site = INST_CONTINUE;
	    for (j=0 ; j<4 ; j++) {
		*++site = INST_NOP;
	    }
	} else {







|
>







3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
    }
    for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
	site = envPtr->codeStart + auxPtr->continueTargets[i];
	if (rangePtr->continueOffset == -1) {
	    int j;

	    /*
	     * WTF? Can't bind, so revert to an INST_CONTINUE. Not enough
	     * space to do anything else.
	     */

	    *site = INST_CONTINUE;
	    for (j=0 ; j<4 ; j++) {
		*++site = INST_NOP;
	    }
	} else {
Changes to generic/tclCompile.h.
116
117
118
119
120
121
122





123
124
125
126
127
128
129
				 * to calculate the number of POPs required to
				 * restore the stack to its prior state. */
    int expandTarget;		/* The number of expansions expected on the
				 * auxData stack at the time the loop starts;
				 * we can't currently discard them except by
				 * doing INST_INVOKE_EXPANDED; this is a known
				 * problem. */





    int numBreakTargets;	/* The number of [break]s that want to be
				 * targeted to the place where this loop
				 * exception will be bound to. */
    int *breakTargets;		/* The offsets of the INST_JUMP4 instructions
				 * issued by the [break]s that we must
				 * update. Note that resizing a jump (via
				 * TclFixupForwardJump) can cause the contents







>
>
>
>
>







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
				 * to calculate the number of POPs required to
				 * restore the stack to its prior state. */
    int expandTarget;		/* The number of expansions expected on the
				 * auxData stack at the time the loop starts;
				 * we can't currently discard them except by
				 * doing INST_INVOKE_EXPANDED; this is a known
				 * problem. */
    int expandTargetDepth;	/* The stack depth expected at the outermost
				 * expansion within the loop. Not meaningful
				 * if there have are no open expansions
				 * between the looping level and the point of
				 * jump issue. */
    int numBreakTargets;	/* The number of [break]s that want to be
				 * targeted to the place where this loop
				 * exception will be bound to. */
    int *breakTargets;		/* The offsets of the INST_JUMP4 instructions
				 * issued by the [break]s that we must
				 * update. Note that resizing a jump (via
				 * TclFixupForwardJump) can cause the contents
767
768
769
770
771
772
773



774
775
776
777
778
779
780
781
782
783
784
#define INST_ARRAY_EXISTS_IMM		160
#define INST_ARRAY_MAKE_STK		161
#define INST_ARRAY_MAKE_IMM		162

#define INST_INVOKE_REPLACE		163

#define INST_LIST_CONCAT		164



#define INST_VERIFY			165

/* The last opcode */
#define LAST_INST_OPCODE		165

/*
 * Table describing the Tcl bytecode instructions: their name (for displaying
 * code), total number of code bytes required (including operand bytes), and a
 * description of the type of each operand. These operand types include signed
 * and unsigned integers of length one and four bytes. The unsigned integers
 * are used for indexes or for, e.g., the count of objects to push in a "push"







>
>
>
|


|







772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
#define INST_ARRAY_EXISTS_IMM		160
#define INST_ARRAY_MAKE_STK		161
#define INST_ARRAY_MAKE_IMM		162

#define INST_INVOKE_REPLACE		163

#define INST_LIST_CONCAT		164

#define INST_EXPAND_DROP		165

#define INST_VERIFY			166

/* The last opcode */
#define LAST_INST_OPCODE		166

/*
 * Table describing the Tcl bytecode instructions: their name (for displaying
 * code), total number of code bytes required (including operand bytes), and a
 * description of the type of each operand. These operand types include signed
 * and unsigned integers of length one and four bytes. The unsigned integers
 * are used for indexes or for, e.g., the count of objects to push in a "push"
982
983
984
985
986
987
988


989
990
991
992
993
994
995
 *----------------------------------------------------------------
 * Procedures shared among Tcl bytecode compilation and execution modules but
 * not used outside:
 *----------------------------------------------------------------
 */

MODULE_SCOPE void	TclCleanupByteCode(ByteCode *codePtr);


MODULE_SCOPE void	TclCompileCmdWord(Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int count,
			    CompileEnv *envPtr);
MODULE_SCOPE void	TclCompileExpr(Tcl_Interp *interp, const char *script,
			    int numBytes, CompileEnv *envPtr, int optimize);
MODULE_SCOPE void	TclCompileExprWords(Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int numWords,







>
>







990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
 *----------------------------------------------------------------
 * Procedures shared among Tcl bytecode compilation and execution modules but
 * not used outside:
 *----------------------------------------------------------------
 */

MODULE_SCOPE void	TclCleanupByteCode(ByteCode *codePtr);
MODULE_SCOPE void	TclCleanupStackForBreakContinue(CompileEnv *envPtr,
			    ExceptionAux *auxPtr);
MODULE_SCOPE void	TclCompileCmdWord(Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int count,
			    CompileEnv *envPtr);
MODULE_SCOPE void	TclCompileExpr(Tcl_Interp *interp, const char *script,
			    int numBytes, CompileEnv *envPtr, int optimize);
MODULE_SCOPE void	TclCompileExprWords(Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int numWords,
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
	*(envPtr)->codeNext++ =						\
		(unsigned char) ((unsigned int) (i) >> 16);		\
	*(envPtr)->codeNext++ =						\
		(unsigned char) ((unsigned int) (i) >>  8);		\
	*(envPtr)->codeNext++ =						\
		(unsigned char) ((unsigned int) (i)      );		\
    } while (0)
#endif;

/*
 * Macros to emit an instruction with signed or unsigned integer operands.
 * Four byte integers are stored in "big-endian" order with the high order
 * byte stored at the lowest address. The ANSI C "prototypes" for these macros
 * are:
 *







|







1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
	*(envPtr)->codeNext++ =						\
		(unsigned char) ((unsigned int) (i) >> 16);		\
	*(envPtr)->codeNext++ =						\
		(unsigned char) ((unsigned int) (i) >>  8);		\
	*(envPtr)->codeNext++ =						\
		(unsigned char) ((unsigned int) (i)      );		\
    } while (0)
#endif

/*
 * Macros to emit an instruction with signed or unsigned integer operands.
 * Four byte integers are stored in "big-endian" order with the high order
 * byte stored at the lowest address. The ANSI C "prototypes" for these macros
 * are:
 *
Changes to generic/tclExecute.c.
2734
2735
2736
2737
2738
2739
2740











2741
2742
2743
2744
2745
2746
2747
	    Tcl_Panic("Bad stack estimate = %d; truth = %ld", estimate,
		    CURR_DEPTH - (auxObjList ? auxObjList->length : 0));
	}
#endif
	NEXT_INST_F(5, 0, 0);
    }













    case INST_EXPAND_STKTOP: {
	int i;
	ptrdiff_t moved;

#ifdef TCL_COMPILE_DEBUG
	/*







>
>
>
>
>
>
>
>
>
>
>







2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
	    Tcl_Panic("Bad stack estimate = %d; truth = %ld", estimate,
		    CURR_DEPTH - (auxObjList ? auxObjList->length : 0));
	}
#endif
	NEXT_INST_F(5, 0, 0);
    }

    case INST_EXPAND_DROP:
	/*
	 * Drops an element of the auxObjList, popping stack elements to
	 * restore the stack to the state before the point where the aux
	 * element was created.
	 */

	CLANG_ASSERT(auxObjList);
	objc = CURR_DEPTH - auxObjList->internalRep.ptrAndLongRep.value;
	POP_TAUX_OBJ();
	NEXT_INST_V(1, objc, 0);

    case INST_EXPAND_STKTOP: {
	int i;
	ptrdiff_t moved;

#ifdef TCL_COMPILE_DEBUG
	/*
Changes to tests/for.test.
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878




























































879
880
881
882
883
884
885
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.3 {Bug 3614226: ensure that break cleans up the expansion stack} {memory knownBug} {
    apply {{} {
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    for {set x 0} {[incr x]<50} {} {
		puts {*}[puts a b c {*}[break] d e f]
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.4 {Bug 3614226: ensure that continue cleans up the expansion stack} {memory knownBug} {
    apply {{} {
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    for {set x 0} {[incr x]<50} {} {
		puts {*}[puts a b c {*}[continue] d e f]
	    }




























































	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0








|













|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
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
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.3 {Bug 3614226: ensure that break cleans up the expansion stack} memory {
    apply {{} {
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    for {set x 0} {[incr x]<50} {} {
		puts {*}[puts a b c {*}[break] d e f]
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.4 {Bug 3614226: ensure that continue cleans up the expansion stack} memory {
    apply {{} {
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    for {set x 0} {[incr x]<50} {} {
		puts {*}[puts a b c {*}[continue] d e f]
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.5 {Bug 3614226: ensure that break cleans up the combination of main and expansion stack} memory {
    apply {{} {
	set l [lrepeat 50 p q r]
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    for {set x 0} {[incr x]<50} {} {
		puts [puts {*}$l {*}[puts a b c {*}$l {*}[break] d e f]]
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.6 {Bug 3614226: ensure that continue cleans up the combination of main and expansion stack} memory {
    apply {{} {
	set l [lrepeat 50 p q r]
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    for {set x 0} {[incr x]<50} {} {
		puts [puts {*}$l {*}[puts a b c {*}$l {*}[continue] d e f]]
	    }
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.7 {Bug 3614226: ensure that break only cleans up the right amount} memory {
    apply {{} {
	set l [lrepeat 50 p q r]
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
		puts [puts {*}$l {*}[puts a b c {*}$l {*}[break] d e f]]
	    }]
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0
test for-7.8 {Bug 3614226: ensure that continue only cleans up the right amount} memory {
    apply {{} {
	set l [lrepeat 50 p q r]
	# Can't use [memtest]; must be careful when we change stack frames
	set end [meminfo]
	for {set i 0} {$i < 5} {incr i} {
	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
		puts [puts {*}$l {*}[puts a b c {*}$l {*}[continue] d e f]]
	    }]
	    set tmp $end
	    set end [meminfo]
	}
	expr {$end - $tmp}
    }}
} 0

Changes to unix/configure.
6612
6613
6614
6615
6616
6617
6618





6619
6620
6621
6622
6623
6624
6625
	if test $tcl_cv_cc_visibility_hidden = yes; then


cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE extern __attribute__((__visibility__("hidden")))
_ACEOF







fi


fi









>
>
>
>
>







6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
	if test $tcl_cv_cc_visibility_hidden = yes; then


cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE extern __attribute__((__visibility__("hidden")))
_ACEOF


cat >>confdefs.h <<\_ACEOF
#define HAVE_HIDDEN 1
_ACEOF


fi


fi


7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"

fi

	    case $system in
	    FreeBSD-3.*)
	    	# FreeBSD-3 doesn't handle version numbers with dots.
	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
	    	TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname,\$@"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'







<
<
<
<
<
<
<
<





|







7828
7829
7830
7831
7832
7833
7834








7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"

fi









	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$@"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
    if test "$tcl_cv_cc_visibility_hidden" != yes; then


cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE extern
_ACEOF


cat >>confdefs.h <<\_ACEOF
#define NO_VIZ
_ACEOF


fi


    if test "$SHARED_LIB_SUFFIX" = ""; then

	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'







<
<
<
<
<







9049
9050
9051
9052
9053
9054
9055





9056
9057
9058
9059
9060
9061
9062
    if test "$tcl_cv_cc_visibility_hidden" != yes; then


cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE extern
_ACEOF







fi


    if test "$SHARED_LIB_SUFFIX" = ""; then

	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
Changes to unix/tcl.m4.
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	CFLAGS=$hold_cflags
	AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	    AC_DEFINE(MODULE_SCOPE,
		[extern __attribute__((__visibility__("hidden")))],
		[Compiler support for module scope symbols])

	])
    ])

    # Step 0.d: Disable -rpath support?

    AC_MSG_CHECKING([if rpath support is requested])
    AC_ARG_ENABLE(rpath,







>







1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	CFLAGS=$hold_cflags
	AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	    AC_DEFINE(MODULE_SCOPE,
		[extern __attribute__((__visibility__("hidden")))],
		[Compiler support for module scope symbols])
	    AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
	])
    ])

    # Step 0.d: Disable -rpath support?

    AC_MSG_CHECKING([if rpath support is requested])
    AC_ARG_ENABLE(rpath,
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    ])
	    case $system in
	    FreeBSD-3.*)
	    	# FreeBSD-3 doesn't handle version numbers with dots.
	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
	    	TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])







<
<
<
<
<
<
<
<





|







1534
1535
1536
1537
1538
1539
1540








1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    ])








	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
	    [No Compiler support for module scope symbols])
	AC_DEFINE(NO_VIZ, [], [No visibility attribute])
    ])

    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'])
    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"







<







2037
2038
2039
2040
2041
2042
2043

2044
2045
2046
2047
2048
2049
2050
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
	    [No Compiler support for module scope symbols])

    ])

    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
	SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'])
    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
	UNSHARED_LIB_SUFFIX='${VERSION}.a'])
    DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"
Changes to unix/tclConfig.h.in.
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

/* Do we have a usable 'union wait'? */
#undef NO_UNION_WAIT

/* Do we have <values.h>? */
#undef NO_VALUES_H

/* No visibility attribute */
#undef NO_VIZ

/* Do we have wait3() */
#undef NO_WAIT3

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT








|
|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

/* Do we have a usable 'union wait'? */
#undef NO_UNION_WAIT

/* Do we have <values.h>? */
#undef NO_VALUES_H

/* Compiler support for module scope symbols */
#undef HAVE_HIDDEN

/* Do we have wait3() */
#undef NO_WAIT3

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

Changes to win/configure.
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
fi


else

  ZLIB_OBJS=\${ZLIB_OBJS}

  cat >>confdefs.h <<_ACEOF
#define NO_VIZ 1
_ACEOF


fi


cat >>confdefs.h <<\_ACEOF
#define HAVE_ZLIB 1
_ACEOF







<
<
<
<







4373
4374
4375
4376
4377
4378
4379




4380
4381
4382
4383
4384
4385
4386
fi


else

  ZLIB_OBJS=\${ZLIB_OBJS}






fi


cat >>confdefs.h <<\_ACEOF
#define HAVE_ZLIB 1
_ACEOF
Changes to win/configure.in.
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  AS_IF([test "$do64bit" = "yes"], [
    AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win64/zdll.lib])
  ], [
    AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib])
  ])
], [
  AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
  AC_DEFINE_UNQUOTED(NO_VIZ, 1)
])
AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])

AC_CHECK_TYPE([intptr_t], [
    AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
    for tcl_cv_intptr_t in "int" "long" "long long" none; do







<







131
132
133
134
135
136
137

138
139
140
141
142
143
144
  AS_IF([test "$do64bit" = "yes"], [
    AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win64/zdll.lib])
  ], [
    AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib])
  ])
], [
  AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])

])
AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])

AC_CHECK_TYPE([intptr_t], [
    AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
    AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
    for tcl_cv_intptr_t in "int" "long" "long long" none; do