summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2018-10-18 14:58:28 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2018-10-18 14:58:28 (GMT)
commite0064189465e2ea63ca9e2dd531928a14c968f52 (patch)
treed291965a7b623423224119db98788ab42009c7eb /generic
parent2881b5c3df298c14a851a8bed7d618a5761f4274 (diff)
downloadtcl-e0064189465e2ea63ca9e2dd531928a14c968f52.zip
tcl-e0064189465e2ea63ca9e2dd531928a14c968f52.tar.gz
tcl-e0064189465e2ea63ca9e2dd531928a14c968f52.tar.bz2
Tests for advanced object mutation issues.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclOODefineCmds.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c
index c924d2b..f5fe676 100644
--- a/generic/tclOODefineCmds.c
+++ b/generic/tclOODefineCmds.c
@@ -1083,6 +1083,8 @@ TclOODefineClassObjCmd(
{
Object *oPtr;
Class *clsPtr;
+ Foundation *fPtr = TclOOGetFoundation(interp);
+ int wasClass, willBeClass;
/*
* Parse the context to get the object to operate on.
@@ -1118,12 +1120,20 @@ TclOODefineClassObjCmd(
if (clsPtr == NULL) {
return TCL_ERROR;
}
-
+ if (oPtr == clsPtr->thisPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not change classes into an instance of themselves", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+ return TCL_ERROR;
+ }
/*
* Set the object's class.
*/
+ wasClass = (oPtr->classPtr != NULL);
+ willBeClass = (TclOOIsReachable(fPtr->classCls, clsPtr));
+
if (oPtr->selfCls != clsPtr) {
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
TclOODecrRefCount(oPtr->selfCls->thisPtr);
@@ -1131,6 +1141,16 @@ TclOODefineClassObjCmd(
AddRef(oPtr->selfCls->thisPtr);
TclOOAddToInstances(oPtr, oPtr->selfCls);
+ /*
+ * Create or delete the class guts if necessary.
+ */
+
+ if (wasClass && !willBeClass) {
+ /* TODO: DELETE THE STRUCTURE */
+ } else if (!wasClass && willBeClass) {
+ /* TODO: CREATE THE STRUCTURE */
+ }
+
if (oPtr->classPtr != NULL) {
BumpGlobalEpoch(interp, oPtr->classPtr);
} else {