views:

188

answers:

1

I'm trying to implement a basic object-oriented ANSI C runtime and using Objective-C as a guide.

They're seems to be three parts. A Class Description, Class Interface, and Class Implementation. In order for the Class Interface to be instantiated, the familiar method of using the Class object to instantiate one's object can only happen if the runtime has already instantiated your class object using the class description.

So are all Class definitions allocated statically at first run to provide the ability to instantiate using the Class object? Or if they are allocated dynamically (on initial call), how? Is it a part of the run loop or is the Class actually a function that determines if it has already been allocated or not prior to forwarding the message?

+3  A: 

The runtime does some initialization via constructor functions that get called before actual program execution. They go by __attribute__((constructor)) in both gcc and clang.

In the case of Objective-C some of them are embedded in the binary by the compiler. You would have to include them in your headers for similar effect.

These functions use data automatically embedded by the compiler. They do things such as building hash tables for the class lookup function which are then used for the actual message passing.

Instances on the other hand are allocated dynamically.

I am doing something similar, so I don't really know a lot better than that, but this is as deep as I have dug.

jbcreix
So, the Obj-C lexer, inside the compiler, generates generic class descriptions from your interface (.h file), stores the list in a hash table for class lookup, but what triggers the initialization using the mentioned constructors? doesn't something have to be called in main to set this up?
Anderson
The compiler injects call to the runtime's constructors at compile-time?
Anderson
No, there is a section of the binary called .ctors that contains a list of function pointers to be called. That list is written to by the compiler-linker from the list of functions which have a constructor attribute and executed either at the startup code if a static library or by the initialization code in dynamic linked files.
jbcreix
By startup code I mean C runtime code that gets linked automatically. It calls them by default. However, the linker has to include the constructor which for static libraries only works if the function has been referenced elsewhere.
jbcreix
The hash table at least in the GNU runtime is generated by these constructors. The Apple implementation might do some of this statically.
jbcreix
Am I following?Compiler:1. Determine metaclass descriptions based on Class interfaces2. Generate constructor functions for the Class object instantiation3. Inject sequenced function pointers to all constructor functions into the .ctor section using the __attribute__((constructor)) callRun-Time:1. libobjc shared library is opened2. Obj-C runtime instantiates the root metaclass and class3. program binary initializes its metaclasses and classes as part of .ctor section4. program binary's main section begins processing
Anderson
I am not sure about your Compiler(and runtime) step 2. The constructor functions generate runtime meta-data. The Class objects, and all the relevant data, etc. are already generated at compile-time(think static structures). Basically what happens is 1- libobjc and module files add meta-data 2- main is executed/ BTW, the Root class isn't magic in ObjC it is just another class which provides for all its children.
jbcreix
A module(.m file) constructor is a function that calls the runtime with a pointer to the compiler generated Module structure, which contains references to everything else.
jbcreix
Yes, that's what I was getting at. How is the module structure (class description) stored? As @encoded type descriptors i.e. struct { int i; float f[3]; int a:3; int b:2; char c;} converted to {?=i[3f]b128i3b131i2c}
Anderson
Because I'm not interested in doing compiler parsing or building out a seperate runtime at the moment, in ANSI C, would it be possible to use a generalized constructor that reads all the type descriptors and generate class objects at runtime.
Anderson
Of course, that is done for convenience, but if you had your class descriptions stored in data files you could build the structures you need from a file. The difference is that the compiled Objc generates structures that are readily usable by the runtime, so you would be doing that part of the work JIT.
jbcreix