Tcl Source Code

Check-in [4b47ba25b7]
Login

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

Overview
Comment:Shift more burden of smart cleanup onto the TclFreeCompileEnv() routine. Stop crashes when the hookProc raises an error.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-4-branch
Files: files | file ages | folders
SHA1: 4b47ba25b7df9c7b02b80d68eb9ba707d48abf0b
User & Date: dgp 2013-02-22 17:38:16
Context
2013-02-22
18:26
Shift more burden of smart cleanup onto the TclFreeCompileEnv() routine. Stop crashes when the hookP... check-in: 06abbd6e02 user: dgp tags: core-8-5-branch
18:24
Use iPtr field instead of source field to mark a CompileEnv as uninitialized. envPtr->source == NULL... check-in: 5c01d3bd75 user: dgp tags: core-8-4-branch
17:38
Shift more burden of smart cleanup onto the TclFreeCompileEnv() routine. Stop crashes when the hookP... check-in: 4b47ba25b7 user: dgp tags: core-8-4-branch
2013-02-21
21:14
Protect against multiple uses of a CompileEnv with only one initialization. Make TclFreeCompileEnv s... Closed-Leaf check-in: a9d0d6fd73 user: dgp tags: aku-review
03:04
3605447 Make sure the -clear option to [namespace export] always clears, whether or not new export p... check-in: 5c65fe2f73 user: dgp tags: core-8-4-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.







1
2
3
4
5
6
7






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

	* generic/tclNamesp.c:	[Bug 3605447] Make sure the -clear option
	* tests/namespace.test:	to [namespace export] always clears, whether
	or not new export patterns are specified.

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







1
2
3
4
5
6
7
8
9
10
11
12
13
2013-02-22  Don Porter  <[email protected]>

	* generic/tclCompile.c:	Shift more burden of smart cleanup onto the
	* generic/tclExecute.c:	TclFreeCompileEnv() routine.  Stop crashes
	when the hookProc raises an error.

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

	* generic/tclNamesp.c:	[Bug 3605447] Make sure the -clear option
	* tests/namespace.test:	to [namespace export] always clears, whether
	or not new export patterns are specified.

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

Changes to generic/tclCompile.c.

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    CompileHookProc *hookProc;	/* Procedure to invoke after compilation. */
    ClientData clientData;	/* Hook procedure private data. */
{
    Interp *iPtr = (Interp *) interp;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */
    LiteralTable *localTablePtr = &(compEnv.localLitTable);
    register AuxData *auxDataPtr;
    LiteralEntry *entryPtr;
    register int i;
    int length, nested, result;
    char *string;
#ifdef TCL_TIP280
    ContLineLoc* clLocPtr;
#endif
#ifdef TCL_COMPILE_DEBUG
    if (!traceInitialized) {







<
<
<







357
358
359
360
361
362
363



364
365
366
367
368
369
370
    CompileHookProc *hookProc;	/* Procedure to invoke after compilation. */
    ClientData clientData;	/* Hook procedure private data. */
{
    Interp *iPtr = (Interp *) interp;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */
    LiteralTable *localTablePtr = &(compEnv.localLitTable);



    int length, nested, result;
    char *string;
#ifdef TCL_TIP280
    ContLineLoc* clLocPtr;
#endif
#ifdef TCL_COMPILE_DEBUG
    if (!traceInitialized) {
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
	 * objects and aux data items is given to the ByteCode object.
	 */
    
#ifdef TCL_COMPILE_DEBUG
	TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/


	TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
	if (tclTraceCompile >= 2) {
	    TclPrintByteCodeObj(interp, objPtr);
	}
#endif /* TCL_COMPILE_DEBUG */
    }
	
    if (result != TCL_OK) {
	/*
	 * Compilation errors. 
	 */

	entryPtr = compEnv.literalArrayPtr;
	for (i = 0;  i < compEnv.literalArrayNext;  i++) {
	    TclReleaseLiteral(interp, entryPtr->objPtr);
	    entryPtr++;
	}
#ifdef TCL_COMPILE_DEBUG
	TclVerifyGlobalLiteralTable(iPtr);
#endif /*TCL_COMPILE_DEBUG*/

	auxDataPtr = compEnv.auxDataArrayPtr;
	for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
	    if (auxDataPtr->type->freeProc != NULL) {
		auxDataPtr->type->freeProc(auxDataPtr->clientData);
	    }
	    auxDataPtr++;
	}
    }


    /*
     * Free storage allocated during compilation.
     */
    
    if (localTablePtr->buckets != localTablePtr->staticBuckets) {
	ckfree((char *) localTablePtr->buckets);
    }







>
|

|
|
|

|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451




452



















453
454
455
456
457
458
459
	 * objects and aux data items is given to the ByteCode object.
	 */
    
#ifdef TCL_COMPILE_DEBUG
	TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/

	if (result == TCL_OK) {
	    TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
	    if (tclTraceCompile >= 2) {
		TclPrintByteCodeObj(interp, objPtr);
	    }
#endif /* TCL_COMPILE_DEBUG */
	}
    }




	



















    /*
     * Free storage allocated during compilation.
     */
    
    if (localTablePtr->buckets != localTablePtr->staticBuckets) {
	ckfree((char *) localTablePtr->buckets);
    }
943
944
945
946
947
948
949


























950
951
952
953
954
955
956
 *----------------------------------------------------------------------
 */

void
TclFreeCompileEnv(envPtr)
    register CompileEnv *envPtr; /* Points to the CompileEnv structure. */
{


























    if (envPtr->mallocedCodeArray) {
	ckfree((char *) envPtr->codeStart);
    }
    if (envPtr->mallocedLiteralArray) {
	ckfree((char *) envPtr->literalArrayPtr);
    }
    if (envPtr->mallocedExceptArray) {







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







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
954
955
956
957
 *----------------------------------------------------------------------
 */

void
TclFreeCompileEnv(envPtr)
    register CompileEnv *envPtr; /* Points to the CompileEnv structure. */
{
    if (envPtr->source) {
	/* 
	 * We never converted to Bytecode, so free the things we would
	 * have transferred to it.
	 */

	int i;
	LiteralEntry *entryPtr = envPtr->literalArrayPtr;
	AuxData *auxDataPtr = envPtr->auxDataArrayPtr;

	for (i = 0;  i < envPtr->literalArrayNext;  i++) {
	    TclReleaseLiteral((Tcl_Interp *)envPtr->iPtr, entryPtr->objPtr);
	    entryPtr++;
	}

#ifdef TCL_COMPILE_DEBUG
	TclVerifyGlobalLiteralTable(envPtr->iPtr);
#endif /*TCL_COMPILE_DEBUG*/

	for (i = 0;  i < envPtr->auxDataArrayNext;  i++) {
	    if (auxDataPtr->type->freeProc != NULL) {
		auxDataPtr->type->freeProc(auxDataPtr->clientData);
	    }
	    auxDataPtr++;
	}
    }
    if (envPtr->mallocedCodeArray) {
	ckfree((char *) envPtr->codeStart);
    }
    if (envPtr->mallocedLiteralArray) {
	ckfree((char *) envPtr->literalArrayPtr);
    }
    if (envPtr->mallocedExceptArray) {
1083
1084
1085
1086
1087
1088
1089




1090
1091
1092
1093
1094
1095
1096
#ifdef TCL_TIP280
    /* TIP #280 */
    ExtCmdLoc* eclPtr = envPtr->extCmdMapPtr;
    int* wlines = NULL;
    int  wlineat, cmdLine;
    int* clNext;
#endif





    Tcl_DStringInit(&ds);

    if (numBytes < 0) {
	numBytes = strlen(script);
    }
    Tcl_ResetResult(interp);







>
>
>
>







1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
#ifdef TCL_TIP280
    /* TIP #280 */
    ExtCmdLoc* eclPtr = envPtr->extCmdMapPtr;
    int* wlines = NULL;
    int  wlineat, cmdLine;
    int* clNext;
#endif

    if (envPtr->source == NULL) {
	Tcl_Panic("TclCompileScript() called on uninitialized CompileEnv");
    }

    Tcl_DStringInit(&ds);

    if (numBytes < 0) {
	numBytes = strlen(script);
    }
    Tcl_ResetResult(interp);
1986
1987
1988
1989
1990
1991
1992




1993
1994
1995
1996
1997
1998
1999
    int numLitObjects = envPtr->literalArrayNext;
    Namespace *namespacePtr;
    int i;
#ifdef TCL_TIP280
    int new;
#endif
    Interp *iPtr;





    iPtr = envPtr->iPtr;

    codeBytes = (envPtr->codeNext - envPtr->codeStart);
    objArrayBytes = (envPtr->literalArrayNext * sizeof(Tcl_Obj *));
    exceptArrayBytes = (envPtr->exceptArrayNext * sizeof(ExceptionRange));
    auxDataArrayBytes = (envPtr->auxDataArrayNext * sizeof(AuxData));







>
>
>
>







1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
    int numLitObjects = envPtr->literalArrayNext;
    Namespace *namespacePtr;
    int i;
#ifdef TCL_TIP280
    int new;
#endif
    Interp *iPtr;

    if (envPtr->source == NULL) {
	Tcl_Panic("TclInitByteCodeObj() called on uninitialized CompileEnv");
    }

    iPtr = envPtr->iPtr;

    codeBytes = (envPtr->codeNext - envPtr->codeStart);
    objArrayBytes = (envPtr->literalArrayNext * sizeof(Tcl_Obj *));
    exceptArrayBytes = (envPtr->exceptArrayNext * sizeof(ExceptionRange));
    auxDataArrayBytes = (envPtr->auxDataArrayNext * sizeof(AuxData));
2106
2107
2108
2109
2110
2111
2112



2113
2114
2115
2116
2117
2118
2119
     * byte code object (internal rep), for use with the bc compiler.
     */

    Tcl_SetHashValue (Tcl_CreateHashEntry (iPtr->lineBCPtr, (char*) codePtr, &new),
		      envPtr->extCmdMapPtr);
    envPtr->extCmdMapPtr = NULL;
#endif



}

/*
 *----------------------------------------------------------------------
 *
 * LogCompilationInfo --
 *







>
>
>







2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
     * byte code object (internal rep), for use with the bc compiler.
     */

    Tcl_SetHashValue (Tcl_CreateHashEntry (iPtr->lineBCPtr, (char*) codePtr, &new),
		      envPtr->extCmdMapPtr);
    envPtr->extCmdMapPtr = NULL;
#endif

    /* We've used up the CompileEnv.  Mark as uninitialized. */
    envPtr->source = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * LogCompilationInfo --
 *

Changes to generic/tclExecute.c.

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
    Interp *iPtr = (Interp *) interp;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */
    LiteralTable *localTablePtr = &(compEnv.localLitTable);
    register ByteCode *codePtr = NULL;
    				/* Tcl Internal type of bytecode.
				 * Initialized to avoid compiler warning. */
    AuxData *auxDataPtr;
    LiteralEntry *entryPtr;
    Tcl_Obj *saveObjPtr;
    char *string;
    int length, i, result;

    /*
     * First handle some common expressions specially.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);
    if (length == 1) {







<
<


|







720
721
722
723
724
725
726


727
728
729
730
731
732
733
734
735
736
    Interp *iPtr = (Interp *) interp;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */
    LiteralTable *localTablePtr = &(compEnv.localLitTable);
    register ByteCode *codePtr = NULL;
    				/* Tcl Internal type of bytecode.
				 * Initialized to avoid compiler warning. */


    Tcl_Obj *saveObjPtr;
    char *string;
    int length, result;

    /*
     * First handle some common expressions specially.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);
    if (length == 1) {
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
	    /*
	     * Compilation errors. Free storage allocated for compilation.
	     */

#ifdef TCL_COMPILE_DEBUG
	    TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/
	    entryPtr = compEnv.literalArrayPtr;
	    for (i = 0;  i < compEnv.literalArrayNext;  i++) {
		TclReleaseLiteral(interp, entryPtr->objPtr);
		entryPtr++;
	    }
#ifdef TCL_COMPILE_DEBUG
	    TclVerifyGlobalLiteralTable(iPtr);
#endif /*TCL_COMPILE_DEBUG*/
    
	    auxDataPtr = compEnv.auxDataArrayPtr;
	    for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
		if (auxDataPtr->type->freeProc != NULL) {
		    auxDataPtr->type->freeProc(auxDataPtr->clientData);
		}
		auxDataPtr++;
	    }
	    TclFreeCompileEnv(&compEnv);
	    goto done;
	}

	/*
	 * Successful compilation. If the expression yielded no
	 * instructions, push an zero object as the expression's result.







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<







802
803
804
805
806
807
808




809











810
811
812
813
814
815
816
	    /*
	     * Compilation errors. Free storage allocated for compilation.
	     */

#ifdef TCL_COMPILE_DEBUG
	    TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/




    











	    TclFreeCompileEnv(&compEnv);
	    goto done;
	}

	/*
	 * Successful compilation. If the expression yielded no
	 * instructions, push an zero object as the expression's result.