summaryrefslogtreecommitdiffstats
path: root/generic/tclOO.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2018-10-19 10:06:23 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2018-10-19 10:06:23 (GMT)
commitfca6e38924437639527aca6bdeb434a00f3169ea (patch)
treeec57c10036ec449293a55d7ec8f2d213539ca2d1 /generic/tclOO.c
parente7392a5c2218ae1a8c95f1172fba911c9e7b110a (diff)
parent09446c7544e32d0eca9c0c68d7917729e6c33ee8 (diff)
downloadtcl-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.c96
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;