New clear Objective-C

I have come here to chew bubblegum and write code ... and I'm all out of bubblegum.

Monday, February 27, 2006

Modern furniture disasters, the LC2 club chair

I can laugh about it now, but at one point in my life when I had more money than sense I was completely obsessed with modern design. The icons of modernity would simplify and enhance my life in ways that ordinary things could not. Afterall, they were designed by people who had a vision of the future. Items of modern design were relatively expensive and this meant I would be getting what I paying for, of course.

Of course. Of course, I was young and naive. The reality is that a great deal of modern design looks cool but is completely overpriced and impractical. Masterful marketing and I fell for it.

This is the Le Corbusier LC2 club chair, I've had one about 6 years now:



I'll leave lessons on Le Corbusier to the historians, so I'll just say that this chair sucks. The height of the back is cripplingly low, the depth of the seat barely supports your legs, I know the welds are going to break eventually because the frame flexes outward too much and the cushions are completely uncomfortable high density foam. Only my shortest guests don't complain about it.

Even Emma looks miserable in it.

Tuesday, February 21, 2006

Thanks for the stool softener

Yes, this is for real.

Call from an in-law mp3

I captured and cropped this using Audacity, nice app, and free.

Sunday, February 19, 2006

The mansion Steve wants to tear down

This is an aerial photograph of the Jackling mansion in Woodside, CA from the 70's.



A close relative of mine bought it in the 70's and sold it to Steve in the 80's. They had bought the place in poor condition, fixed it up and lived there with their family. This photo looks early in the ownership as some of the things fixed up and added are not present. The pool at the top of the picture is on the large size and divided by property lines as part of the estate being chopped up, it was left intact but later filled in, so you could see the tile edging along the ground. The tennis courts stayed part of the estate. A smaller pool was added near the parking spaces on the left. The huge pipe organ exists in the upper right of the house as part of an addition. The upper left contains a library on the first floor, a spiral staircase and bedrooms on the second floor. The lower left is a separate guest house. The main portion of the house is a living area, then a large kitchen to the right. Fitting for Jackling the copper magnate, the mailbox was thick solid copper and was on a solid copper post that ran deep in the ground.

I stayed at the house once in the early 80's during a short vacation. It was a pretty cool place and in very nice condition when I went. It was modernized, the pipe organ functioned and was quite impressive. It's not insanely big but definitely a memorable experience. My memory is of large hills as a backdrop and a huge sweeping well manicured lawn.

Apparently Steve let the place get really run down and has been wanting to tear it down, but has run into various preservationist groups in the process. The town granted Steve a demolition permit, but in January a judge sided with preservationists and the house still stands.

The site is gorgeous, I can't blame him for wanting to live there. I am guessing it is no fun being stuck with the giant hulk of a house which is falling apart. Too bad it got to that point though.

What would you do?

Monday, February 13, 2006

Irony

gcc -fnext-runtime -fconstant-string-class=NSString_constant objc_msgSend.s -o objc_msgSend.o
cc1: warning: command line option "-fnext-runtime" is valid for ObjC/ObjC++ but not for C
cc1: warning: command line option "-fconstant-string-class=NSString_constant" is valid for ObjC/ObjC++ but not for C

gcc -fnext-runtime -fconstant-string-class=NSString_constant NSString_constant.s -o NSString_constant.o
cc1: warning: command line option "-fnext-runtime" is valid for ObjC/ObjC++ but not for C
cc1: warning: command line option "-fconstant-string-class=NSString_constant" is valid for ObjC/ObjC++ but not for C

Sunday, February 12, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #7, conclusion

Like all good ties, this smackdown tie will have people arguing for a long time, who really won, who is better? Everyone is silently thinking "I want to be on the winning side"

There are no winners here. Due to how gcc is partitioned into -fnext-runtime and -fgnu-runtime, the GNU runtime is losing out on work that Apple is doing for Objective-C, and if someone other than Apple wants to use -fnext-runtime they need to do a lot of work to get their runtime going. If the differences between the runtime interfaces could be straightened out, there would be a lot less duplicative effort being made and hosting Objective-C on a given platform would not be as much work.

The GNU runtime interface started out being just a different function interface to the same data structures. Over time, people used the -fgnu-runtime flag as an excuse to neglect the data structures in libobjc or to bastardize the existing ones in the name of experimentation.

I say get rid of -fgnu-runtime, make the function interface the default. But keep libobjc up to date on the data structures, and for the love of all things good, get rid of typed selectors, they are terrible. NeXT's and Apple's performance oriented dispatch functions can be turned on if desired. Some enterprising people could update libobjc to support the NeXT dispatching if desired, and the new performance oriented ones that Apple has been adding. It would benefit everyone.

Summary

- Get rid of typed selectors
- Unify the data structures used in both runtimes, follow NeXT's/Apple's lead here
- Use the current -fgnu-runtime function interface as the default

Add two compiler flags:

-fobjc-enable-msgsend this would generate NeXT style dispatch calls
-fobjc-period-symbols this would generate NeXT style object code symbols with the period in them.

This would bring the original spirit of -fgnu-runtime interface back and make it the default. The performance oriented, but not so portable, NeXT and Apple changes can be integrated into libobjc if desired. Everyone out there using Objective-C somewhere other than Mac OS X could benefit from these changes and it would streamline the Objective-C support in gcc.

Friday, February 10, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #6, symbols

The lights come back up at the smackdown and the bell rings, GNU runtime interface is looking rejuvenated as the cocky NeXT runtime interface dances around the ring. When the lights were low, the GNU runtime interface's manager tucked a pair of underscores into the gloves. GNU runtime interface comes out strong and socks the NeXT runtime interface in the eye. Oh, that has got to hurt.

gcc emits object file symbols for classes and categories. Afterall, it is nice to be able to reference classes in other object files isn't it. I don't know about categories though, is this actually used? Anyway. There are actually a couple (as in two) ways to reference classes in other object files. One is objc_get_class/objc_getClass, this asks the runtime for a class. A call to this function with the classes name can be generated instead of a direct reference. The alternative is to generate actual object file symbols for the class.

-fnext-runtime generates class symbols which look like this:

_.objc_class_name_MyClass

-fgnu-runtime generates class symbols which look like this:

___objc_class_name_MyClass

The thing is, these really have nothing to do with the runtime, the runtime doesn't care about object file symbols. They are strictly platform specific, some linkers can deal with periods in symbols, some can't.

I have no idea why NeXT chose to use a period in a symbol, probably to keep the linking namespace a little more organized, either way, it's not entirely portable. The mainline binutils can not deal with these symbols on Windows, I expect it is a similar situation on other platforms.

-fgnu-runtime wins out on this one, but not by much. Underscores should be the default.

Add a compiler flag -fobjc-period-symbols to enable the NeXT style.

-fgnu-runtime: 2
-fnext-runtime: 2

Wednesday, February 08, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #5, hooks

The lights at the smackdown go dim and the local high school dance club puts on a show for the audience. In the dim lighting you notice that the GNU runtime interface and NeXT runtime interface look awfully similar.

objc_get_class and objc_getClass are functionally identical.
objc_getMetaClass and objc_get_meta_class are functionally identical.
__objc_execClass and __objc_exec_class are functionally identical.

I understand people are attached to their names. The new compiler flag -fobjc-enable-msgsend described in smackdown #2 would emit NeXT style, the default would emit GNU style. Seems fair.

Monday, February 06, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #4, class instances

*ding* *ding* the round is over. NeXT and GNU interfaces go in their corners to take a breather. The referee and judges go into a huddle. The crowd is wondering what is going on. It looks like there is some sort of technical question in the air and the ref. is getting some input. The referee leaves the huddle, shaking his head, no point for either runtime on this technical difference.


struct objc_class {
struct objc_class *isa;
struct objc_class *superclass;
const char *name;
long version;
long info;
long instanceSize;
OBJCInstanceVariableList *ivars;
OBJCMethodList **methodLists;
OBJCMethodCache *cache;
#ifdef USE_GNU_RUNTIME
struct objc_class *subclasses;
struct objc_class *sibling;
#endif
OBJCProtocolList *protocols;
#ifndef USE_GNU_RUNTIME
void *gc_object_type;
#else
void *sel_id;
void *gc_object_type;
#endif
};


Before I get into this, the class struct needs a field, let's call it privateRuntimeJunk, or private_runtime_junk if you prefer, which can be used by the runtime for anything it wants and it stores all of its private business off of that field. This would clean a lot of this up.

subclasses and sibling are two such private runtime specific fields. subclasses is the head of a linked list of, of course, subclasses. sibling is the next class in the list. They are not generated at compile time. They are computed at runtime and are only used in the slightly extreme case of adding methods to an already initialized class. The GNU runtime uses them to re-build the method cache in all of a classes subclasses when the parent class adds a method. Does this really belong in the class structure? Can't they be computed? or, stored in private_runtime_junk.

gc_object_type, same deal, but from what I can tell, it does need to be stored instead of computed. Another candidate for private_runtime_junk. Especially since this is only used when you're using garbage collection.

sel_id was added to the NeXT runtime in Panther. I have been unable to determine what it is for, another candidate for privateRuntimeJunk ?

Can the NeXT runtime and GNU runtime agree on what a class instance should look like?

Smackdown results, no change:

-fnext-runtime: 2
-fgnu-runtime: 1

Sunday, February 05, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #3, symbol tables

While the GNU runtime interface is thrusting it's arms in the air chanting victory to the crowd, the NeXT runtime interface stands up and gives the GNU runtime a one-two punch to the kidneys. Ouch, that's gotta hurt folks. Watch your back GNU runtime interface!

Sometime after the original GNU runtime was written, NeXT added constant strings and protocols to the language. This consisted in a subtle change in the Objective-C symbol table.

Speaking in object code here, an Objective-C program consists of one or more object files (think .o's), inside each object file is an array of Objective-C modules, these modules are the main entry point into the compile time data structures. The runtime is given these modules at startup and it traverses the modules, plucking out selectors, classes, categories, constant strings and protocols to initialize and put in the runtime information.

Each module has some information like a version, size, name and then a symbol table. The symbol table is where the bulk of the information lives.

This is what the symbol table looks like:


typedef struct OBJCSymbolTable {
unsigned long selectorRefCount;
SEL *selectorReferences;
unsigned short classDefCount;
unsigned short categoryDefCount;
#ifndef USE_GNU_RUNTIME
int objectDefCount;
int protocolDefCount;
#endif
void *defs[1]; /* variable size */
} OBJCSymbolTable;


The GNU runtime does not use objectDefCount and protocolDefCount. They never updated to it, no idea why not. But at some point they did add constant strings and protocols, just not here.

Instead of adding objectDefCount, they tacked the constant string information onto the end of defs as a null terminated array. Oof. NeXT runtime gets a backstabbing punch to the left kidney.

Instead of adding protocolDefCount, they initialize protocols off the class structure. This means that a protocol can not exist if it not tied to a class. Oof Oof. The NeXT runtime get in a second punch to the right kidney.

Update: The static instances array in the GNU runtime actually does put Protocols in there, yet there are no other classes supported. So this is the same thing as the NeXT runtime, done differently. Why? GNU runtime still loses.

The worst part about this is that when they added constant strings to the symbol table they actually enhanced the feature so that it could accomodate constants of other classes, array, dictionary, etc. But that never went anywhere. If they had just put the effort into updating the symbol table!

GNU runtime folks, please update the symbol table. Really, it's just not that big of a deal to change. Don't be afraid of change!

Smackdown results;

-fnext-runtime: 2
-fgnu-runtime: 1

Friday, February 03, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #2, objc_msg_lookup

With typed selectors so badly slammed in the last post you would think the GNU runtime interface is down on the mat bleeding from the head, ok, it is, but it's still conscious and heroically regains it's strength in a Hulk like fashion, rising up to smash the NeXT runtime interface squarely in the face.

objc_msg_lookup and objc_msg_lookup_super are really good, well thought out functions.

When you're trying to bootstrap your own Objective-C runtime on a new system, these functions are invaluable, they can be easily written in C and recompiled anywhere. No assembly required. Beautiful, I love it. And even better, if it's in C and available to the compiler it can be inlined.

My proposal;

- Make gcc default to objc_msg_lookup, no flags for it
- Add a new compiler flag, -fobjc-enable-msgsend which uses objc_msgSend and it's variants instead of objc_msg_lookup.

Yes, gcc does default to objc_msg_lookup right now, but with that you get all sorts of other ugliness which do not befit objc_msg_lookup's superior design.

Smackdown results;

-fgnu-runtime: 1
-fnext-runtime:1

Thursday, February 02, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #1, typed selectors

Ancient history. NeXT came out with a technology called "Distributed Objects", or DO for short. The current implementation exists today inside their Foundation framework. The original implementation was not even based on Foundation and was not implemented as cleanly as the current incarnation, it had some problems which Foundation fixed.

Some programmers decided they wanted their own version of this original DO and it would sit on top of the GNU runtime. Without a clear vision of how DO worked, in part due to the lack of documentation and more open interface from NeXT, they would implement DO in a way which they thought was right. What they thought was Right would ask of the GNU runtime to do things which it could not possibly do reliably.

I won't beat around the bush on this. Typed selectors were a Big Mistake. They should be phased out of use.

To understand how typed selectors came about, one needs to understand a major idea behind DO. In Objective-C when an object does not respond to a message, the runtime does what is called "forwarding". It invokes a known/predefined method which takes the selector, the arguments from the stack/registers and asks the object what it wants to do with them. The default implementation is typically to error out, raise an exception, quit, up to the runtime.

DO came up with this fantastic idea to have an almost implementation-less object called a "proxy", which takes these forwards and sends them over the network to the implementation on a remote host. Instead of code generation and stubs, they use the runtime type information to encode the arguments.

The problem is that when you are given a forward all you have is a name and the arguments. No type information. How to implement this became more obvious with the release of OpenStep, but typed selectors predate OpenStep and a lot of people outside of NeXT were not as clear on how things should be done.

The way it works today is that before a proxy is asked to forward a message, the type information for the message is requested. The proxy asks the remote implementation how the types are encoded and uses this information to encode the arguments of the forward for transmit and how to decode the return value.

The guys trying to write DO on their own either didn't know this or thought this was not a good implementation. Why ask the remote system when you can have the compiler encode the type information locally, in the selector! This seems like a good idea on the surface but it breaks a cardinal rule of Objective-C.

Selectors are supposed to be unique

On the surface this doesn't seem like a big deal, but it has this evil little side effect. You can have multiple selectors with the same name and different types. If you need to get the types when all you have is the name, the results are not reliably defined, because there can be multiple typed selectors with the same name and different types.

How to fix typed selectors

Get rid of them. Implement them the way they are supposed to be, a name<->unique id mapping. Typically the unique id is the name, but it doesn't have to be.

Ack, but getting rid of things is not so easy in software, someone somewhere is probably using them. They are used in, of course, GNUStep, the inheritor of the old free DO implementation. Let's take a look at how GNUStep is using typed selectors.

There are two functions we are interested in. sel_get_type, this takes the name of a selector and returns the types associated with it, if they are present. It is possible to have a "typed selector" with no types! The other function of interest is sel_get_any_uid.

sel_get_any_uid should have been the little guy on the programmers shoulder going "Dude, this looks really wrong". sel_get_any_uid takes a name and returns *ANY* typed selector with that name. If there are two selectors with different types, it will return one of them. So just sit and pray it returns the right one, and somewhere out there in the sea of selectors, there isn't another method with the same name and different types.

Let's talk about sel_get_type, since if you are using sel_get_type you may be using sel_get_any_uid. To get rid of sel_get_type means you can get rid of sel_get_any_uid.

sel_get_type is only used in GNUStep base, their Foundation work-alike. I pulled down gnustep-base-1.11.2 and looked for sel_get_type. It shows up in these files:

mframe.m, cifframe.m, callframe.m
GSFFIInvocation.m
GSFFCallInvocation.m
NSDistantObject.m
NSConnection.m
NSInvocation.m

---

It turns out that mframe, cifframe and callframe are copy&paste versions of the same code with variations. Their use of sel_get_type is the same. The interesting thing about them is that they also implement their functionality in terms of the NeXT runtime interface. So, sel_get_type isn't actually needed here. It exists, someone used it. It's use can be easily removed.

---

GSFFIInvocation.m and GSFFCallInvocation are also copy&paste versions of the same code with variations. From GSFFInvocation.m:


/* Determine the method types so we can construct the frame. We may not
get the right one, though. What to do then? Perhaps it can be fixed up
in the callback, but only under limited circumstances.
*/
sel_type = sel_get_type (sel);


This is a perfect example of where a comment is appropriate. It flags the use of sel_get_type as broken and a better way to do things is needed. I rest my case on GSFFIInvocation and GSFFCallInvocation.

---

The people working on NSDistantObject know what they're doing. They have deprecated the use of sel_get_type in favor of the right way to do it. I don't need to say anything here. But why not get rid of this code altogether?


/**
* For backward compatibility ... do not use this method.

* Returns the type information ... the modern way of doing this is
* with the -methodSignatureForSelector: method.
*/
- (const char *) selectorTypeForProxy: (SEL)selector
{
#if NeXT_RUNTIME
/* This isn't what we want, unless the remote machine has
the same architecture as us. */
const char *t;
t = [_connection typeForSelector: selector remoteTarget: _handle];
return t;
#else /* NeXT_runtime */
return sel_get_type (selector);
#endif
}


---
NSConnection has an interesting use of sel_get_type


/* get the method types from the selector */
#if NeXT_RUNTIME
[NSException
raise: NSGenericException
format: @"Sorry, distributed objects does not work with NeXT runtime"];
/* type = [object selectorTypeForProxy: sel]; */
#else
type = sel_get_type(sel);
if (type == 0 || *type == '\0')
{
type = [[object methodSignatureForSelector: sel] methodType];
if (type)
{
sel_register_typed_name(GSNameFromSelector(sel), type);
}
}
#endif


It attempts to look up the types of the selector, if they are not found, it asks the proxy for the types, it then maps the result to a name. So, in effect it is doing the right thing by using methodSignatureForSelector, but all it does with typed selectors is use them as a global cache for name to type mapping. How this should be done is to always call methodSignatureForSelector: and leave it up to the proxy to implement a cache. A cache which properly maps names and types localized for the proxy's remote implementation, not the entire runtime. If the proxy did this, the NeXT runtime version would work fine too.

---
NSInvocation.m

This is the last use of sel_get_type, so far all the other uses have been hugely flawed, let's see what is happened here.


- (id) initWithSelector: (SEL)aSelector
{
const char *types;
NSMethodSignature *newSig;

types = sel_get_type(aSelector);
if (types == 0)
{
types = sel_get_type(sel_get_any_typed_uid(GSNameFromSelector(aSelector)));
}
if (types == 0)
{
NSLog(@"Couldn't find encoding type for selector %s.",
GSNameFromSelector(aSelector));
RELEASE(self);
return nil;
}
newSig = [NSMethodSignature signatureWithObjCTypes: types];
return [self initWithMethodSignature: newSig];
}


Let's examine the second use first:

types = sel_get_type(sel_get_any_typed_uid(GSNameFromSelector(aSelector)));

Because sel_get_any_typed_uid's result can be not reliable, the use of sel_get_type with the return value is flawed. This needs to be another way. But let's look at the first use before we do that.

The first use looks very innocuous, but wait, what is initWithSelector: doing in NSInvocation to begin with. An NSInvocation should only come to exist with a NSMethodSignature. initWithSelector: is bypassing NSMethodSignature in favor of using typed selectors. Use NSMethodSignature's and initWithSelector: goes away.

The GNUStep guys know what their doing, the problem is that they are afraid to let go of the old code. Understandable, but let it go man, just let it go.

If you are absolutely desperate for them, create gcc -ftyped-selectors and maintain your own broken runtime which supports them.

Smackdown results

-fnext-runtime: 1
-fgnu-runtime: 0

Wednesday, February 01, 2006

-fnext-runtime vs. -fgnu-runtime smackdown, #0, introduction

Long ago and far away, well, for me at least, some Really Smart guys at NeXT Computer modified gcc to support Objective-C and released the changes back out into the public, because, well, they were obligated to under the GPL. What they were not obligated to release was the actual runtime needed to effectively use the compiler changes. So, some other Really Smart people who wanted a runtime wrote one which worked with the compiler changes and released it as free software as part of gcc. They actually improved upon the NeXT runtime in one aspect and saw a vision of Objective-C working everywhere in a more portable fashion. They changed the primary dispatch function from objc_msgSend to one called objc_msg_lookup, the subtle difference being that objc_msgSend must be written in assembler, whereas objc_msg_lookup can be written in C. The assembly needed to tie everything together for a particular platform was kept in the compiler. Very smart guys.

You could choose between these two runtime interfaces with compiler flags, -fnext-runtime and -fgnu-runtime. gcc became the de facto Objective-C compiler in the world and has remained to this day.

But something happened along the way. As with most Really Smart people, they don't sit around, and the guys who implemented the original GNU runtime interface moved on to other things. Their creation, -fgnu-runtime, was left out in the cold for someone else to come along and take care of.

Someone did come along and try to take care of -fgnu-runtime, but as with many foster parents they had Good Intentions but did not Understand -fgnu-runtime like a creator would. They tried to understand -fgnu-runtime, but pushed it to do some things it didn't want to do and neglected some of it's strengths.

The new caretakers were trying to create some new software and felt that -fgnu-runtime could help them if only it would do some new things that would make their life easier, or so they thought. Cinderella was put on dish duty.

What happened?

Instead of just being a difference in the function interface, people started to also modify the data structures that -fgnu-runtime generated. The major changes are:

- Heavily altered the behavior of a selector to support "typed selectors".
- Neglected to keep the object code data structures up to date with the NeXT changes
- Modified the object code data structures to support some things which aren't really needed in the object code data structures.

This caused a split in Objective-C, the NeXT runtime camp and the GNU runtime camp. The two runtimes vary so much that conventions in one are not supported in the other. So, there are effectively two Objective-C's and this bothers me.

I maintain my own Objective-C runtime which is neither Apple nor GNU. For a long time I hobbled along supporting both interfaces, the NeXT interface on Windows using the old YellowBox compiler and the GNU interface on Linux and Solaris with newer compilers. I have largely ignored the problem until now. I need to update my compiler suite and unify my runtime so it is supports one interface.

But what is happening is that while I prefer the NeXT data structures, objc_msg_lookup is very handy when moving to new platforms. So I end up creating my own version of gcc which supports the conventions I need.

Ugh. A third runtime interface. This is not good.

I decided to examine what I needed to unify the runtime interfaces and what compiler changes I would need to make.

This is the first in a series of posts on the differences between the -fnext-runtime and -fgnu-runtime interfaces. I will detail the strengths and benefits of each interface and how they can co-exist to make Objective-C a more compelling force in the world of software. This is not about the implementation of the runtimes, rather about compiler standardization. The runtime API's are a whole other topic!

Before these two runtime interfaces can agree, they've got to duke it out and settle their differences. Let the -fnext-runtime vs. -fgnu-runtime smackdown begin!