
While studying the GNU Objective-C runtime, I wondered if it might be possible to address one of the most common complaints leveled at Objective-C: that its dynamic nature makes it too slow to be used for time-critical applications, such as a game engine. The most obvious place to look for this loss of speed is in the messaging code, since unlike traditional object-oriented languages, method calls are not linked to method implementations until runtime.
The use of sparse arrays in the GNU runtime is inspired, particularly when compared to the hacks and workarounds that Apple implemented in order to speed up their hashtable-based implementation. In considering whether or not the runtime could be made faster, I knew I wanted to keep the sparse array idea. I also identified a few places where I thought the runtime library itself might be made more efficient. For example, the GNU runtime builds an entire class hierarchy in order to ensure that +load is run in the correct order -- that is, that the method of a superclass is executed before the method of its subclasses. I thought there might be simpler ways to approach the problem.
Three years later, the result of my studies and tinkering is the Polar Objective-C runtime.
The library provides an alternative implementation of an Objective-C runtime library that can be used with GCC. It went through several iterations: from Pascal, to C++, and finally to a combination of C and Objective-C code. One of the major differences is that the C portions of the library are also object-oriented, using a system similar to that of GLib.
Originally I was concerned with trying to maintain API compatibility with the GNU runtime library, but as the library evolved I grew away from that idea because I'm not really a fan of the scheme used to name functions, which is somewhat inconsistent. To be fair, some of this inconsistency seems to derive from the GNU runtime's desire to be compatible with earlier Apple/NeXT code -- but, in the end, I wanted a more consistent interface; and, where possible, I wanted the library interface to be handled through Objective-C code rather than through C function calls. The idea behind this is that a Foundation Library is then free to present a C interface to its clients.
It is still possible to obtain a measure of API compatibility, if it's needed -- but:
- This runtime does not include native support for garbage collection; that is easily provided by a Foundation Library instead
- This runtime does not include native support for GCC exceptions. This also means that it cannot support the
@synchronized()directive, since the compiler requires you to build with support for GCC exceptions in order to use these. However, there are substitutes for both exception handling and synchronized blocks, by way of$try,$catch(), and$synchronized().
There is a list of additional differences between the runtimes at the project page. Taken together, however, they mean that full API compatibility with the GNU Objective-C runtime is unlikely.
I've tested the basic functionality of the library on Devuan with GCC 11, and on Windows 10 with both MSYS2 and Cygwin. I also tested it on MacOS Sequoia with a Homebrew installation of GCC 14 and had some success -- but given how difficult Apple makes it to use tools other than XCode for MacOS development, this will probably be the end of my attempts to support MacOS.
I'd like to write some documentation for the library and finish testing its various systems to make sure they work. Longer term, I'm thinking of trying my hand at an Objective-C compiler -- something like the Portable Object Compiler, maybe -- because I have some additional ideas on how to improve the overall messaging speed of the runtime, and these will require some support from the compiler.
An Objective-C runtime library
