diff options
author | dkf <dkf@noemail.net> | 2008-09-01 00:35:40 (GMT) |
---|---|---|
committer | dkf <dkf@noemail.net> | 2008-09-01 00:35:40 (GMT) |
commit | 1d48ca2d0bd9271d923f7696a1adb36d68fa7a4b (patch) | |
tree | 2579a1e6cb4beb302aec6d4a4b47951bd41033cb /generic/tclOO.c | |
parent | 3ba1247021052286637c6c74dea44047b6fb3c4f (diff) | |
download | tcl-1d48ca2d0bd9271d923f7696a1adb36d68fa7a4b.zip tcl-1d48ca2d0bd9271d923f7696a1adb36d68fa7a4b.tar.gz tcl-1d48ca2d0bd9271d923f7696a1adb36d68fa7a4b.tar.bz2 |
Improve the semantics of C-implemented destructors slightly.
FossilOrigin-Name: 879ea220fd5c7722445e38216126c4f64dd6da41
Diffstat (limited to 'generic/tclOO.c')
-rw-r--r-- | generic/tclOO.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/generic/tclOO.c b/generic/tclOO.c index 95926f2..b25f070 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclOO.c,v 1.15 2008/08/20 15:41:26 dkf Exp $ + * RCS: @(#) $Id: tclOO.c,v 1.16 2008/09/01 00:35:42 dkf Exp $ */ #ifdef HAVE_CONFIG_H @@ -548,6 +548,7 @@ ObjectRenamedTrace( { Object *oPtr = clientData; Class *clsPtr; + CallContext *contextPtr; /* * If this is a rename and not a delete of the object, we just flush the @@ -570,24 +571,22 @@ ObjectRenamedTrace( AddRef(oPtr); oPtr->flags |= OBJECT_DELETED; - if (!Tcl_InterpDeleted(interp)) { - CallContext *contextPtr = TclOOGetCallContext(oPtr, NULL, DESTRUCTOR); - if (contextPtr != NULL) { - int result; - Tcl_InterpState state; + contextPtr = TclOOGetCallContext(oPtr, NULL, DESTRUCTOR); + if (contextPtr != NULL) { + int result; + Tcl_InterpState state; - contextPtr->callPtr->flags |= DESTRUCTOR; - contextPtr->skip = 0; - state = Tcl_SaveInterpState(interp, TCL_OK); - result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, - 0, NULL); - if (result != TCL_OK) { - Tcl_BackgroundError(interp); - } - Tcl_RestoreInterpState(interp, state); - TclOODeleteContext(contextPtr); + contextPtr->callPtr->flags |= DESTRUCTOR; + contextPtr->skip = 0; + state = Tcl_SaveInterpState(interp, TCL_OK); + result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, 0, + NULL); + if (result != TCL_OK) { + Tcl_BackgroundError(interp); } + Tcl_RestoreInterpState(interp, state); + TclOODeleteContext(contextPtr); } /* @@ -2134,11 +2133,18 @@ Tcl_ObjectContextInvokeNext( if (contextPtr->index+1 >= contextPtr->callPtr->numChain) { /* - * We're at the end of the chain; generate an error message. + * We're at the end of the chain; generate an error message unless the + * interpreter is being torn down, in which case we might be getting + * here because of methods/destructors doing a [next] (or equivalent) + * unexpectedly. */ const char *methodType; + if (Tcl_InterpDeleted(interp)) { + return TCL_OK; + } + if (contextPtr->callPtr->flags & CONSTRUCTOR) { methodType = "constructor"; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { @@ -2195,11 +2201,18 @@ TclNRObjectContextInvokeNext( if (contextPtr->index+1 >= contextPtr->callPtr->numChain) { /* - * We're at the end of the chain; generate an error message. + * We're at the end of the chain; generate an error message unless the + * interpreter is being torn down, in which case we might be getting + * here because of methods/destructors doing a [next] (or equivalent) + * unexpectedly. */ const char *methodType; + if (Tcl_InterpDeleted(interp)) { + return TCL_OK; + } + if (contextPtr->callPtr->flags & CONSTRUCTOR) { methodType = "constructor"; } else if (contextPtr->callPtr->flags & DESTRUCTOR) { |