--- otcl.c.orig Fri Sep 29 12:48:17 1995 +++ otcl.c Wed Oct 15 13:10:27 1997 @@ -1,6 +1,6 @@ /* -*- Mode: c++ -*- * - * $Id: otcl.c,v 1.38 1995/09/29 19:47:36 djw Exp $ + * $Id: otcl.c,v 1.2 1997/08/01 19:32:29 tecklee Exp $ * * Copyright 1993 Massachusetts Institute of Technology * @@ -792,17 +792,32 @@ hp = Tcl_FirstHashEntry(&obj->variables.varTable, &hs); while (hp != 0) { - do { + for (;;) { Var* vp = (Var*)Tcl_GetHashValue(hp); if (vp->flags != VAR_UNDEFINED) break; hp = Tcl_NextHashEntry(&hs); - } while (hp != 0); + if (hp == 0) + goto done; + } if (hp != 0) { char* name = Tcl_GetHashKey(&obj->variables.varTable, hp); (void)OTclUnsetInstVar(obj, in, name, TCL_LEAVE_ERR_MSG); } hp = Tcl_FirstHashEntry(&obj->variables.varTable, &hs); } +done: + hp = Tcl_FirstHashEntry(&obj->variables.varTable, &hs); + while (hp != 0) { + /* + * We delete the hash table below so disassociate + * each remaining (undefined) var from its hash table entry. + * (Otherwise, tcl will later try to delete + * the already-freed hash table entry.) + */ + Var* vp = (Var*)Tcl_GetHashValue(hp); + vp->hPtr = 0; + hp = Tcl_NextHashEntry(&hs); + } Tcl_DeleteHashTable(&obj->variables.varTable); hp2 = obj->procs ? Tcl_FirstHashEntry(obj->procs, &hs2) : 0; @@ -891,20 +906,24 @@ hPtr = Tcl_FirstHashEntry(&cl->instances, &hSrch); while (hPtr) { - OTclObject* inst = (OTclObject*)Tcl_GetHashKey(&cl->instances, hPtr); - /* * allow circularity for meta-classes */ - - if (inst != (OTclObject*)cl) { - char* name = Tcl_GetCommandName(inst->teardown, inst->id); - (void)Tcl_DeleteCommand(inst->teardown, name); + OTclObject* inst; + for (;;) { + inst = (OTclObject*)Tcl_GetHashKey(&cl->instances, hPtr); + if (inst != (OTclObject*)cl) { + char* name = Tcl_GetCommandName(inst->teardown, inst->id); + (void)Tcl_DeleteCommand(inst->teardown, name); + break; + } + hPtr = Tcl_NextHashEntry(&hSrch); + if (hPtr == 0) + goto done; } hPtr = Tcl_FirstHashEntry(&cl->instances, &hSrch); } - Tcl_DeleteHashTable(&cl->instances); - +done: hPtr = Tcl_FirstHashEntry(&cl->instprocs, &hSrch); for (; hPtr != 0; hPtr = Tcl_NextHashEntry(&hSrch)) { Tcl_CmdInfo* co = (Tcl_CmdInfo*)Tcl_GetHashValue(hPtr); @@ -933,6 +952,8 @@ */ obj->teardown = in; PrimitiveODestroy(cd); + + Tcl_DeleteHashTable(&cl->instances); } @@ -1021,11 +1042,13 @@ hp = Tcl_FirstHashEntry(&obj->variables.varTable, &hs); while (hp != 0) { - do { + for (;;) { Var* vp = (Var*)Tcl_GetHashValue(hp); if (vp->flags != VAR_UNDEFINED) break; hp = Tcl_NextHashEntry(&hs); - } while (hp != 0); + if (hp == 0) + goto done; + } if (hp != 0) { char* name = Tcl_GetHashKey(&obj->variables.varTable, hp); result = OTclUnsetInstVar(obj, in, name, TCL_LEAVE_ERR_MSG); @@ -1034,7 +1057,7 @@ hp = Tcl_FirstHashEntry(&obj->variables.varTable, &hs); } if (hp != 0) return TCL_ERROR; - +done: /* * latch, and call delete command if not already in progress */