Reading iOS app binary files
blog.smartdec.net
blog.smartdec.net
It's so conceptually simple, and (aside from objc_msgSend) you can implement the whole thing in C. libobjc2 has (if I'm counting correctly) 23 .c files, and it includes things you can totally ignore as you're learning, like an ObjC garbage collection implementation that no one uses anymore.
The only tricky part is the message-sending routines, since they have to be written in assembly. But as long as you understand what they're doing (rather than how they're doing it), you don't even need to look at those if you don't want to.
And if you're willing to impose some limitations (maximum number of arguments, no floating-point arguments or return value), it's quite easy to implement a "toy" version of objc_msgSend in pure C.
[0]https://www.mulle-kybernetik.com/weblog/2015/mulle_objc_meta...
Check out Mike Ashes excellent blog about Objective-C, the runtime and many other things:
Why? (context: never touched Objective-C)
Like when you implement coroutines/threads in your language runtime, you're going to implement the context switching part in assembly because you just don't have access to the relevant information (registers/stack/...) from portable C (aside from using setjmp/longjmp maybe).
You could have your own calling convention where arguments aren't passed in registers or on the stack, but are boxed into some container. That way every method's implementation function could have the same signature, taking a pointer to the receiver ("self"), the method name, a box of arguments, and a place to pass the return value back out:
typedef void (*IMP)(id, SEL, struct context *, void **); // arguments are `self`, the method name (`const char *`), a pointer to a structure containing the arguments, and a place to put your return value
I know of at least one Objective-C runtime implementation that does this. It won't be nearly as efficient – you have to pack/unpack the arguments, it pushes a stack frame instead of just jumping to the implementation, etc. – but it would certainly be portable.I thought it was about speed, heh.
But yes – when objc_msgSend is invoked tens of thousands of times/second, you'll write it in ASM to get the performance boost anyway. When you're a compiler or runtime engineer working in a language with as few opportunities for static optimization as Objective-C, you bet your ass you'll squeeze every drop possible from message dispatch.
That's more than I expected. Great work!