From: Mike R. <mik...@gm...> - 2007-08-31 00:26:02
|
My plan for checking for message handlers in instantiable classes will not suffice. I implemented the algorithm completely, only to find that I began with an incorrent implicit assumption. Specifically, I assumed that sizeof (SomethingClass) would be exactly sizeof (SBaseClass) + sizeof (all_its_interfaces) + number_of_messages * sizeof (void*). No dice. For efficiency, compiler implementations are allowed to pad structs, or leave extra space between members. For example, I added some members to SFileClass, and then removed them, but its size remained constant at 192 bytes. The result is that we can't treat every set of 4 bytes as a pointer, as some bytes are actually padding. As far as I can tell, this means that there is no way to check for all message handlers at class initiation time. We have to wait till the message is sent and then check if it is handled. This is bad for speed when typechecking is on, but more importantly, it's bad for catching errors earlier. Still, I'll try to think of a way. The good news is, the actual process of finding a message is now optimized more effectively. Also, our interfaces now beat Java in that we can provide default implementations. Take a look at the Java docs for SObject.clone() and the Cloneable interface, and you can tell it's a mess. You can also tell that the reason it's a mess is that they want to include a default implementation of clone() but only for Cloneable objects... It's definitely ugly. In our implementation, implementing SCloneable guarantees that you can obtain a clone. To make it a deep clone, you just need to handle the message SCloneable::distinguish, which lets you distinguish a clone from the source object. This would typically be done by replacing pointers to the source's member objects with pointers to fresh copies of the source's member objects. (For example, SString's distinguish allocates its own new character array and copies the source's string there.) For a derived class to add to its parent class's distinguish handler, it should handle SCloneable::distinguish with a function that starts with something like s_super_msg (obj, SCloneable, distinguish). s_super_msg() sends a message treating obj as the immediate parent type of its actual type. This way, message handlers can chain up, adding behavior rather than replacing it. So, it's great that we include default handlers, but it's definitely a shame that we can't check for message handlers (yet?) at class initiation time. -Mike |