Mess with obsolete classes???

Nathanael Scharli n.schaerli at gmx.net
Fri Feb 15 09:21:30 UTC 2002


Andreas,

> I see the error as well, but your analysis is entirely wrong ;-)
> It turns out that the error gets reported due to a metaclass having two
> instances. Since #allInstances is implemente in Metaclass as "^Array
> with: thisClass" only one of them is reported back. That leads to having
> "left-over" old instances which means that something is _really_ and I
> mean REALLY broken. The error messages you are seeing could also be
> written as "this must never EVER happen" ;-)

You are right, I didn't analyze that quite correct ;). I just saw that the
error is generated because there is an instance of 'Class class' left and
since it said 'Illegal pointers to instancs found', I checked all the object
references to this instance and saw that it is only referenced by some
method contexts on the runtime stack. However, I didin't look at those
methods in detail so I didn't see that this instance is actually a *new*
instance that is created in one of these methods.

Nevertheless, I think that there is also a problem caused by the circular
meta-structure. This does not occur when you add a new instance variable to
'Class', but it occurs when you change the superclass of 'Class'. (In fact,
this is what I did in my image). So, try the following:

1) Create a new subclass of 'ClassDescription' that defines new instance
variables.
2) Change the superclass of 'Class' to this new class and accept

What happens is that the ClassBuilder wants to change the shape of 'Class'
and it therefore calls 'ClassBuilder>>mutate:to:' for all the subclasses. At
one point, 'Class class' is mutated and this reshapes its instance 'Class'.
(Your fix made this work correctly). After all the subclasses are reshaped,
the ClassBuilder calls 'ClassBuilder>>update:to:' to update 'Class' itself.
But since the instance has already been touched before, it is in an
inconsistent state and it brakes.

This is the reason why I modified the ClassBuilder so that it changes 'Class
class' and its instance at the end of the process and not in the middle.
This ensures that 'Class' is still in the expected shape when it is used as
an argument to 'ClassBuilder>>update:to:'. (With other words, my change
makes sure that 'ClassBuilder>>update:to:' is called first with the argument
'Class' and then with 'Class class' instead of doing it the other way
round). Considering the circular meta-structure of Squeak this seems a
reasonable way to do it without applying too many dirty tricks. What do you
think?


Okay, now let me come back to the issue of the strange obsolete classes
sored in the SystemDictionary. The thing I don't like about them is the fact
that they have regular classes as superclasses, but they neither appear as
obsolete subclasses nor as regular subclasses of these classes. As a
consequence, they do not get reshaped when we reshape their superclasses:

In 'ClassBuilder>>mutate:to:', the line

	subs _ oldClass subclasses asArray, oldClass obsoleteSubclasses.      (*)

does *not* include them.

As a consequence, these classes get in an inconsistent state, which is bad
because they are still referenced by some parts of the code.

Therefore my questions:

1) Why do these classes not appear as obsolete subclasses of their
superclasses?
2) Why are these classes stored in the SystemDictionary (with strings as
keys!)?
3) Shouldn't we change this so that the class hierarchy is consistent (means
if a class B has a superclass A, then B is either a regular subclass or an
obsolete subclass of A).

Of course, I can modify the line (*) in the method
'ClassBuilder>>mutate:to:' so that also these strange obsolete subclasses
are included, but it seems to me that it would be better to tackle the
*real* problem, which is the fact that these obsolete classes are stored in
such a messy (inconsistent) way.

Cheers,
Nathanael




More information about the Squeak-dev mailing list