diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2018-10-19 10:06:23 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2018-10-19 10:06:23 (GMT) |
commit | fca6e38924437639527aca6bdeb434a00f3169ea (patch) | |
tree | ec57c10036ec449293a55d7ec8f2d213539ca2d1 /generic/tclOO.c | |
parent | e7392a5c2218ae1a8c95f1172fba911c9e7b110a (diff) | |
parent | 09446c7544e32d0eca9c0c68d7917729e6c33ee8 (diff) | |
download | tcl-fca6e38924437639527aca6bdeb434a00f3169ea.zip tcl-fca6e38924437639527aca6bdeb434a00f3169ea.tar.gz tcl-fca6e38924437639527aca6bdeb434a00f3169ea.tar.bz2 |
merge core-8-6-branch
Diffstat (limited to 'generic/tclOO.c')
-rw-r--r-- | generic/tclOO.c | 96 |
1 files changed, 63 insertions, 33 deletions
diff --git a/generic/tclOO.c b/generic/tclOO.c index c8471d5..0c18390 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -59,7 +59,6 @@ static const struct { * Function declarations for things defined in this file. */ -static Class * AllocClass(Tcl_Interp *interp, Object *useThisObj); static Object * AllocObject(Tcl_Interp *interp, const char *nameStr, Namespace *nsPtr, const char *nsNameStr); static int CloneClassMethod(Tcl_Interp *interp, Class *clsPtr, @@ -84,8 +83,6 @@ static void ObjectNamespaceDeleted(ClientData clientData); static void ObjectRenamedTrace(ClientData clientData, Tcl_Interp *interp, const char *oldName, const char *newName, int flags); -static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr); -static void DeleteDescendants(Tcl_Interp *interp,Object *oPtr); static inline void RemoveClass(Class **list, int num, int idx); static inline void RemoveObject(Object **list, int num, int idx); static inline void SquelchCachedName(Object *oPtr); @@ -451,10 +448,10 @@ InitClassSystemRoots( /* Stand up a phony class for bootstrapping. */ fPtr->objectCls = &fakeCls; - /* referenced in AllocClass to increment the refCount. */ + /* referenced in TclOOAllocClass to increment the refCount. */ fakeCls.thisPtr = &fakeObject; - fPtr->objectCls = AllocClass(interp, + fPtr->objectCls = TclOOAllocClass(interp, AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); /* Corresponding TclOODecrRefCount in KillFoudation */ AddRef(fPtr->objectCls->thisPtr); @@ -470,7 +467,7 @@ InitClassSystemRoots( fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; fPtr->objectCls->flags |= ROOT_OBJECT; - fPtr->classCls = AllocClass(interp, + fPtr->classCls = TclOOAllocClass(interp, AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); /* Corresponding TclOODecrRefCount in KillFoudation */ AddRef(fPtr->classCls->thisPtr); @@ -839,15 +836,15 @@ ObjectRenamedTrace( /* * ---------------------------------------------------------------------- * - * DeleteDescendants -- + * TclOODeleteDescendants -- * * Delete all descendants of a particular class. * * ---------------------------------------------------------------------- */ -static void -DeleteDescendants( +void +TclOODeleteDescendants( Tcl_Interp *interp, /* The interpreter containing the class. */ Object *oPtr) /* The object representing the class. */ { @@ -864,7 +861,8 @@ DeleteDescendants( /* This condition also covers the case where mixinSubclassPtr == * clsPtr */ - if (!Deleted(mixinSubclassPtr->thisPtr)) { + if (!Deleted(mixinSubclassPtr->thisPtr) + && !(mixinSubclassPtr->thisPtr->flags & DONT_DELETE)) { Tcl_DeleteCommandFromToken(interp, mixinSubclassPtr->thisPtr->command); } @@ -883,8 +881,10 @@ DeleteDescendants( if (clsPtr->subclasses.num > 0) { while (clsPtr->subclasses.num > 0) { subclassPtr = clsPtr->subclasses.list[clsPtr->subclasses.num-1]; - if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)) { - Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command); + if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr) + && !(subclassPtr->thisPtr->flags & DONT_DELETE)) { + Tcl_DeleteCommandFromToken(interp, + subclassPtr->thisPtr->command); } TclOORemoveFromSubclasses(subclassPtr, clsPtr); } @@ -906,7 +906,8 @@ DeleteDescendants( * This condition also covers the case where instancePtr == oPtr */ - if (!Deleted(instancePtr) && !IsRoot(instancePtr)) { + if (!Deleted(instancePtr) && !IsRoot(instancePtr) && + !(instancePtr->flags & DONT_DELETE)) { Tcl_DeleteCommandFromToken(interp, instancePtr->command); } TclOORemoveFromInstances(instancePtr, clsPtr); @@ -922,7 +923,7 @@ DeleteDescendants( /* * ---------------------------------------------------------------------- * - * ReleaseClassContents -- + * TclOOReleaseClassContents -- * * Tear down the special class data structure, including deleting all * dependent classes and objects. @@ -930,8 +931,8 @@ DeleteDescendants( * ---------------------------------------------------------------------- */ -static void -ReleaseClassContents( +void +TclOOReleaseClassContents( Tcl_Interp *interp, /* The interpreter containing the class. */ Object *oPtr) /* The object representing the class. */ { @@ -954,9 +955,6 @@ ReleaseClassContents( } else if (IsRootObject(oPtr)) { Tcl_Panic("deleting class structure for non-deleted %s", "::oo::object"); - } else { - Tcl_Panic("deleting class structure for non-deleted %s", - "general object"); } } @@ -1059,6 +1057,7 @@ ReleaseClassContents( if (IsRootClass(oPtr) && !Deleted(fPtr->objectCls->thisPtr)) { Tcl_DeleteCommandFromToken(interp, fPtr->objectCls->thisPtr->command); } + oPtr->classPtr = NULL; } /* @@ -1108,7 +1107,7 @@ ObjectNamespaceDeleted( /* Let the dominoes fall */ if (oPtr->classPtr) { - DeleteDescendants(interp, oPtr); + TclOODeleteDescendants(interp, oPtr); } /* @@ -1237,8 +1236,8 @@ ObjectNamespaceDeleted( /* * Because an object can be a class that is an instance of itself, the - * class object's class structure should only be cleaned after most of the - * cleanup on the object is done. + * class object's class structure should only be cleaned after most of + * the cleanup on the object is done. * * The class of objects needs some special care; if it is deleted (and * we're not killing the whole interpreter) we force the delete of the @@ -1253,7 +1252,7 @@ ObjectNamespaceDeleted( } if (oPtr->classPtr != NULL) { - ReleaseClassContents(interp, oPtr); + TclOOReleaseClassContents(interp, oPtr); } /* @@ -1360,6 +1359,37 @@ TclOOAddToInstances( /* * ---------------------------------------------------------------------- * + * TclOORemoveFromMixins -- + * + * Utility function to remove a class from the list of mixins within an + * object. + * + * ---------------------------------------------------------------------- + */ + +int +TclOORemoveFromMixins( + Class *mixinPtr, /* The mixin to remove. */ + Object *oPtr) /* The object (possibly) containing the + * reference to the mixin. */ +{ + int i, res = 0; + Class *mixPtr; + + FOREACH(mixPtr, oPtr->mixins) { + if (mixinPtr == mixPtr) { + RemoveItem(Class, oPtr->mixins, i); + TclOODecrRefCount(mixPtr->thisPtr); + res++; + break; + } + } + return res; +} + +/* + * ---------------------------------------------------------------------- + * * TclOORemoveFromSubclasses -- * * Utility function to remove a class from the list of subclasses within @@ -1489,10 +1519,10 @@ TclOOAddToMixinSubs( /* * ---------------------------------------------------------------------- * - * AllocClass -- + * TclOOAllocClass -- * - * Allocate a basic class. Does not add class to its - * class's instance list. + * Allocate a basic class. Does not add class to its class's instance + * list. * * ---------------------------------------------------------------------- */ @@ -1516,8 +1546,8 @@ InitClassPath( } } -static Class * -AllocClass( +Class * +TclOOAllocClass( Tcl_Interp *interp, /* Interpreter within which to allocate the * class. */ Object *useThisObj) /* Object that is to act as the class @@ -1758,13 +1788,13 @@ TclNewObjectInstanceCommon( if (TclOOIsReachable(fPtr->classCls, classPtr)) { /* - * Is a class, so attach a class structure. Note that the AllocClass - * function splices the structure into the object, so we don't have - * to. Once that's done, we need to repatch the object to have the - * right class since AllocClass interferes with that. + * Is a class, so attach a class structure. Note that the + * TclOOAllocClass function splices the structure into the object, so + * we don't have to. Once that's done, we need to repatch the object + * to have the right class since TclOOAllocClass interferes with that. */ - AllocClass(interp, oPtr); + TclOOAllocClass(interp, oPtr); TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls); } else { oPtr->classPtr = NULL; |