diff options
author | dgp <dgp@users.sourceforge.net> | 2007-06-21 16:04:54 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2007-06-21 16:04:54 (GMT) |
commit | fa238fdc3fd76a6ec566a17c9d69cdda3b12d2e8 (patch) | |
tree | 412012e773b738aaa21ebf3a1f52e5134820e5c6 /generic/tclExecute.c | |
parent | d02e64d517be20015fde7c0a974fa997eea303f6 (diff) | |
download | tcl-fa238fdc3fd76a6ec566a17c9d69cdda3b12d2e8.zip tcl-fa238fdc3fd76a6ec566a17c9d69cdda3b12d2e8.tar.gz tcl-fa238fdc3fd76a6ec566a17c9d69cdda3b12d2e8.tar.bz2 |
merge updates from HEAD
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index ec5140d..32a0160 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.285.2.7 2007/06/19 02:48:03 dgp Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.285.2.8 2007/06/21 16:04:56 dgp Exp $ */ #include "tclInt.h" @@ -669,6 +669,12 @@ GrowEvaluationStack( return markerPtr + 1; } } else if (needed < 0) { + /* + * Put a marker pointing to the previous marker in this stack, and + * store it in esPtr as the current marker. Return a pointer to one + * word past the marker. + */ + esPtr->markerPtr = ++esPtr->tosPtr; *esPtr->markerPtr = (Tcl_Obj *) markerPtr; return esPtr->markerPtr + 1; @@ -730,6 +736,12 @@ GrowEvaluationStack( newStackReady: eePtr->execStackPtr = esPtr; + /* + * Store a NULL marker at the beginning of the stack, to indicate that + * this is the first marker in this stack and that rewinding to here + * should actually be a return to the previous stack. + */ + esPtr->stackWords[0] = NULL; esPtr->markerPtr = esPtr->tosPtr = &esPtr->stackWords[0]; @@ -774,6 +786,11 @@ StackAllocWords( Tcl_Interp *interp, int numWords) { + /* + * Note that GrowEvaluationStack sets a marker in the stack. This marker + * is read when rewinding, e.g., by TclStackFree. + */ + Interp *iPtr = (Interp *) interp; ExecEnv *eePtr = iPtr->execEnvPtr; Tcl_Obj **resPtr = GrowEvaluationStack(eePtr, numWords, 0); @@ -797,12 +814,33 @@ StackReallocWords( void TclStackFree( - Tcl_Interp *interp) + Tcl_Interp *interp, + void *freePtr) { - Interp *iPtr = (Interp *) interp; - ExecEnv *eePtr = iPtr->execEnvPtr; - ExecStack *esPtr = eePtr->execStackPtr; - Tcl_Obj **markerPtr = esPtr->markerPtr; + Interp *iPtr; + ExecEnv *eePtr; + ExecStack *esPtr; + Tcl_Obj **markerPtr; + + if (interp == NULL) { + Tcl_Free((char *) freePtr); + return; + } + + /* + * Rewind the stack to the previous marker position. The current marker, + * as set in the last call to GrowEvaluationStack, contains a pointer to + * the previous marker. + */ + + iPtr = (Interp *) interp; + eePtr = iPtr->execEnvPtr; + esPtr = eePtr->execStackPtr; + markerPtr = esPtr->markerPtr; + + if ((markerPtr+1) != (Tcl_Obj **)freePtr) { + Tcl_Panic("TclStackFree: incorrect freePtr. Call out of sequence?"); + } esPtr->tosPtr = markerPtr-1; esPtr->markerPtr = (Tcl_Obj **) *markerPtr; @@ -826,14 +864,18 @@ TclStackFree( } } -char * +void * TclStackAlloc( Tcl_Interp *interp, int numBytes) { int numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *); - return (char *) StackAllocWords(interp, numWords); + if (interp == NULL) { + return (void *) Tcl_Alloc(numBytes); + } + + return (void *) StackAllocWords(interp, numWords); } char * @@ -6819,7 +6861,7 @@ TclExecuteByteCode( * Restore the stack to the state it had previous to this bytecode. */ - TclStackFree(interp); + TclStackFree(interp, initCatchTop+1); return result; #undef iPtr } |