what was the second parameter in "id (*IMP)(id, SEL, ...) " used for? - objective-c

my question as the title says.obviously, the first parameter was used for this pointer , in some taste of c++.what about the second one? thak you.

The signature of objc_msgSend() is:
id objc_msgSend(id self, SEL op, ...);
Every method call is compiled down to a call to this function. I.e., if you call:
[anArray objectAtIndex:42];
That will be compiled as if it were:
objc_msgSend(anArray, #selector(objectAtIndex:), 42);
Now, to your question, why do methods get compiled down to a function that has the SEL as the second argument. Or, more specifically, why is this method:
- (id)objectAtIndex:(NSUInteger)index;
Exactly equivalent to this C function:
id object_at_index(id object, SEL _cmd, NSUInteger index);
The answer is speed speed speed.
Speed
Specifically, by doing this, then objc_msgSend() never has to rewrite the stack frame* and it can also use a tail call optimization to jump directly to the method invocation. This is the same reason why you never see objc_msgSend() in backtraces in the debugger (save for when you actually crash/break in the messenger).
objc_msgSend() uses the object and the _cmd to look up the implementation of the method and then, quite literally, jumps to that implementation.
Very fast. Stack frame untouched.
And, as others have stated, having _cmd around in the method implementation can be handy for a variety of reasons. As well, it also means that the messenger can do neat tricks like proxy support via NSInvocation and the like.
*rewriting the stack frame can be insanely complex and expensive. Some of the arguments might be in registers some of the time, etc... All architecture dependent ABI nastiness. One of the biggest challenges to writing things like imp_implementationWithBlock() was figuring out how to do so without touching the stack because doing so would have been too slow and too bloated to be viable.

The purpose of having the second parameter contain the selector is to enable a common dispatch mechanism. As such, the method dispatch code always expects the second parameter to be the selector, and dispatches based on that, or follows the inheritance chain up, or even creates an NSInvocation and calls forwardInvocation:.
Generally, only system-level routines use the selector argument, although it's rather nice to have it when you hit an exception or are in the debugger trying to figure out what routine is giving you difficulties if you are using forwardInvocation

From the documentation:
Discussion
This data type is a pointer to the start of the function that implements the method. This function uses standard C calling conventions as implemented for the current CPU architecture. The first argument is a pointer to self (that is, the memory for the particular instance of this class, or, for a class method, a pointer to the metaclass). The second argument is the method selector. The method arguments follow.
In Objective-C when you call a method you need to know the target, the selector and the eventual arguments. Let's suppose that you are trying to do this manually: how can you know which method to call if you don't know the selector? Do you call some random method? No, you call the right method because you know the method name.

Related

smalltalk: about method- "withArgs:executeMethod:"

I'm trying to understand the method "withArgs: executeMethod: " in smalltalk, squeak.
1. I am trying to understand what is the role of the method?
2. What arguments need to be passed to it for it to be carried out?
A good way to understand this method is by considering it as a syntactic variant of the general expression
object msg: arg (*)
where object is the receiver of the message with selector msg: and arg its argument. There are of course variants with no or multiple arguments, but the idea is the same.
When object receives this message (*) the Virtual Machine (VM) looks up for the CompiledMethod with selector msg: in the object's hierarchy, and transfers it the control, binding self to object and the formal argument of the method to arg.
Notice that this invocation is managed by the VM, no by the Virtual Image (VI). So, how could we reflect the same in the VI? Well, there are two steps in this behavior (1) find the method and (2) bind its formal receiver and arguments to the actual ones and let it run.
Step (1) is the so called lookup algorithm. It is easily implemented in Smalltalk: just ask the receiver its class, check whether the class includes the selector #msg: and, if not, go to the superclass and repeat. If all checks fail, issue the doesNotUnderstand: message.
Step (2) exactly requires what #withArgs:executeMethod: provides. It allows us to say
object withArgs: {arg} executeMethod: method
where method is the CompiledMethod found in step (1). [We have to use {arg} rather than arg because the plural in withArgs: suggests that the method expects an Array of arguments.]
Why would we want this?
Generally speaking, giving the VI the capability to mimic behavior implemented in the VM is good because it makes metaprogramming easier (and more natural).
More practically, a relevant example of the use of this capability is the implementation of Method Wrappers. Briefly described, given any particular method, you can wrap it (as the wrappee) inside a wrapper method, which also has a preBlock. If you then substitute the original method in the MethodDictionary where it belongs, with the wrapper, you can let the wrapper first execute the preBlock and then the intended method. The first task is easy: just send the message preBlock value. For the second we have the method (the wrappee), the receiver and the arguments (if any). So, to complete the task you only need to send to the receiver withArgs:executeMethod: with the actual argument(s) and the wrappee.
Ah! Let's not forget to mention that one of the reasons for having Method Wrappers is to measure testing coverage.
Note also that withArgs:executeMethod: does not require the second argument, i.e., the method to execute, to be in any class, let alone the class of the receiver. In particular, you could create a CompiledMethod on the fly and execute it on any given object. Of course, it is up to you to make sure that the execution will not crash the VM by, say, using the third ivar of the receiver if the receiver has only two etc. A simple way to create a CompiledMethod without installing it in any class is by asking the Smalltalk compiler to do so (look for senders of newCompiler to learn how to do that).

Objective C - What is the difference between IMP and function pointer?

I recently started a project where I require to do swizzling.
After going through many tutorials I got a question, What is the difference between Implementation and function pointer?
From memory, an IMP is a memory-address just like a function pointer, and can be invoked just like an ordinary C function. However it is guaranteed to use objective-C messaging convention, where:
The first argument is the object to operate on (self).
The second argument is the _cmd (SELECTOR) to be invoked. I believe this is so to support dynamic features, such as ObjC message forwarding where we could wrap the original implementation in a proxy, say to start a transaction or perform a security check, or, for a Cocoa specific example, add some property observation cruft, by magic, at run-time. While we already have the function signature, I could be helpful, in some cases, to know "how did I get here?" with the message signature.
Following arguments, if any, are according to the method contract.

Understanding uniqueness of selectors in Objective-C

I am having problem understanding part of the function of "selectors", as described in Apple's guide. I've bolded the parts where I am getting confused:
In Objective-C, selector has two meanings. It can be used to refer
simply to the name of a method when it’s used in a source-code message
to an object. It also, though, refers to the unique identifier that
replaces the name when the source code is compiled. Compiled
selectors are of type SEL. All methods with the same name have the
same selector. You can use a selector to invoke a method on an
object—this provides the basis for the implementation of the
target-action design pattern in Cocoa.
Methods and Selectors For efficiency, full ASCII names are not used as
method selectors in compiled code. Instead, the compiler writes each
method name into a table, then pairs the name with a unique identifier
that represents the method at runtime. The runtime system makes sure
each identifier is unique: No two selectors are the same, and all
methods with the same name have the same selector.
Can anyone explain these bits? Additionally, if different classes have methods with the same name, will they also have the same selector?
All selectors are uniqued -- both at compile time and, dynamically, at runtime through sel_getUid() or the preferred sel_registerName() (the latter being largely preferred, the former still around for historical reasons) -- for speed.
Back story: to call a method, the runtime needs a selector that identifies what is to be called and an object that it will be called on. This is why every single method call in Objective-C has two parameters: the obvious and well known self and the invisible, implied, parameter _cmd. _cmd is the SEL of the method currently executing. That is, you can paste this code into any method to see the name -- the selector -- of the currently executing method:
NSLog(#"%#", NSStringFromSelector(_cmd));
Note that _cmd is not a global; it really is an argument to your method. See below.
By uniquing the selectors, all selector based operations are implemented using pointer equality tests instead of string processing or any pointer de-referencing at all.
In particular, every single time you make a method call:
[someObject doSomething: toThis withOptions: flags]; // calls SEL doSomething:withOptions:
The compiler generates this code (or a very closely related variant):
objc_msgSend(someObject, #selector(doSomething:withOptions:), toThis, flags);
The very first thing objc_msgSend() does is check to see if someObject is nil and short-circuit if it is (nil-eats-message). The next (ignoring tagged pointers) is to look up the selector in someObjects class (the isa pointer, in fact), find the implementation, and call it (using a tail call optimization).
That find the implementation thing has to be fast and to make it really fast, you want the key to finding the implementation of the method to be as fast and stable as possible. To do that, you want the key to be directly usable and globally unique to the process.
Thus, the selectors are uniqued.
That it also happens to save memory is an fantastic benefit, but the messenger would use more memory than it does today if messenging could be made 2x faster (but not 10x for 2x -- or even 2x memory for 2x speed -- while speed is critical, memory use is also critical, certainly).
If you really want to dive deep on how objc_msgSend() works, I wrote a bit of a guide. Note that it is slightly out of date as it was written before tagged pointers, blocks-as-implementation, and ARC were disclosed. I should update the articles.
Yes. Classes do share selectors.
I can give an example from the source code objc-sel.mm, but when you use sel_registerUid() (used behind the scenes in #selector()),
It copies the input string into an internal buffer (if the string hasn't been registered before), for which all future SELs point to.
This is done for less memory usage, and easier message forwarding.
It also, though, refers to the unique identifier that replaces the name when the source code is compiled... All methods with the same name have the same selector.
For this, I refer to an excellent blog post on selectors:
A selector is the same for all methods that have the same name and parameters — regardless of which objects define them, whether those objects are related in the class hierarchy, or actually have nothing to do with each other. At runtime, Objective-C goes to the class and outright asks it, "Do you respond to this selector?", and calls the resulting function pointer if it does.
The runtime system makes sure each identifier is unique: No two selectors are the same, and all methods with the same name have the same selector.
In a screwed up way, this makes sense. If Method A and Method B have the exact same name and arguments, wouldn't it be more efficient to store their selector as one lookup and query the receiver instead of deciding between two basically equally named selectors at runtime?
Look at the SEL type, you don't have to define which class this selector is from, you just give it a method name, for example:
SEL animationSelector = #selector(addAnimation:forKey:);
You can imagine it as a streetname, for example. Many cities can have the same streetnames, but a streetname without a city is worthless. Same for selectors, you can define a selector without adding the object where it's in. But it's complete worthless without fitting class..

In general is invoking and #selector slow?

When creating an iOS program is there any performance hit if I pass around SELs (#selectors) and invoke them in other classes? Is this significantly slower than normal method invocations?
Why would there be a performance hit for messaging (the one thing ObjC is famous for) from other classes? Of course, compared to C functions, there is some overhead (thanks to the addition of two more parts to a method). Selectors are simply data types, so passing them to type SEL is no more costly than sending a BOOL or an int over. However, to actually call a SEL type from a passed selector, the creation of an NSInvocation object is recommended, which would slightly increase the overhead time.
And you are more or less safe in objC, as messages to nil (you did mention other classes), produce nil.
Well it might not have much of effect except on first run as compiler creates a reference to every objects and it's dependencies along with classes at compile time , so it might be a bit slow at loading time(that too in very large programs..) but not much after that provided not very big objects are created in the intermediate steps and also it doesn't involve any large dynamic operation as here i am talking only about calling a local function and calling the same function from a different class.
Anyways why would you use selector to reference to some function in a different class.
From my limited knowledge, a selector is simply an encoding of a method name. Given that in objective-c methods are called by sending messages to objects, I don't see why there should be a performance difference between an explicit method call ([object method]) and an implicit call ([objectDelegate selector]).

Make NSInvocation invoke a specific IMP

I'm looking for a way to make an NSInvocation invoke a specific IMP. By default, it invokes the "lowest" IMP it can find (ie, the most-recently-overridden version), but I'm looking for a way to make it invoke an IMP from higher up in the inheritance chain. The IMP I want to invoke is determined dynamically, or else I'd be able to use the super keyword or something like that.
My thought was to use the -forwardInvocation: mechanism to capture a message (easy and already working) and then alter the IMP so it goes to a method that is neither the super implementation nor the furthest descendent's implementation. (hard)
The only thing I've found that comes remotely close is AspectObjectiveC, but that requires libffi, which makes it non-iOS compatible. Ideally I'd like this to be cross platform.
Any ideas?
disclaimer: i'm just experimenting
Trying out #bbum's idea of a trampoline function
So I think I've got things mostly set up; I've got the following trampoline that gets correctly added via class_addMethod(), and it does get entered:
id dd_trampolineFunction(id self, SEL _cmd, ...) {
IMP imp = [self retrieveTheProperIMP];
self = [self retrieveTheProperSelfObject];
asm(
"jmp %0\n"
:
: "r" (imp)
);
return nil; //to shut up the compiler
}
I've verified that both the proper self and the proper IMP are the right things prior to the JMP, and the _cmd parameter is also coming in properly. (in other words, I correctly added this method).
However, something is going on. I sometimes find myself jumping to a method (usually not the right one) with a nil self and _cmd. Other times I'll just crash in the middle of nowhere with an EXC_BAD_ACCESS. Ideas? (it's been a long time since I've done anything in assembly...) I'm testing this on x86_64.
NSInvocation is just an object representation of a message send. As such, it can't invoke a specific IMP any more than a normal message send could. In order to have an invocation call a specific IMP, you'd either need to write a custom NSInvocation class that goes through the IMP-calling routine or you'd have to write a trampoline that implements the behavior and then create an invocation that represents a message to the trampoline (i.e. you basically wouldn't be using NSInvocation for much of anything).
Added long after the fact, for reference:
You can do it with private API. Put this category somewhere convenient:
#interface NSInvocation (naughty)
-(void)invokeUsingIMP:(IMP)imp;
#end
and voila, it does exactly what you'd expect. I dug up this gem from one of Mike Ash's old blog posts.
Private API tricks like this are great for research or in-house code. Just remember to excise it from your appstore-bound builds.
Given that you already have the IMP, you simply need a way to do a very raw forward of the method call to said IMP. And given that you are willing to use an NSInvocation like solution, then you could also build a similar proxy class.
If I were faced with this, I would create a simple proxying class that contained the IMP to be called and the target object (you'll need to set the self parameter). Then, I would write a trampoline function in assembly that takes the first argument, assumes it is an instance of the proxying class, grabs the self, stuffs it into the register holding argument 0, grabs the IMP and *JMPs to it as a tail call.
With trampoline in hand, you would then add that trampoline as an IMP for any selector on the proxying class that you want forwarded to a particular IMP....
To achieve any kind of generic mechanism like this, the key is to avoid anything having to do with rewriting the stack frame. Avoid the C ABI. Avoid moving arguments about.
An untested idea:
Could you use object_setClass() to force the selection of the IMP that you want? That is…
- (void)forwardInvocation:(NSInvocation *)invocation {
id target = [invocation target];
Class targetClass = classWithTheImpIWant();
Class originalClass = objc_setClass(target, targetClass);
[invocation invoke];
objc_setClass(target, originalClass);
}
I think your best choice is to use libffi. Have you seen the port to iOS at https://github.com/landonf/libffi-ios? I haven't tried the port, but i have successfully invoked IMP with arbitrary arguments on the Mac.
Have a look at JSCocoa https://github.com/parmanoir/jscocoa it includes code to help you prepare a ffi_cif structure from a Method and it also contains a version of libffi that should compile on iOS. (Haven't tested either)
You should probably have a look at how we swizzle the implementation of a certain method on an instance of an object in https://github.com/tuenti/TMInstanceMethodSwizzler
Basically, you swizzle the method for all object of a class so when its called it look up in a dictionary whats is the implementation which has to be called for the target object, falling back to the original implementation if not found.
You can also use the private invokeWithImp: method, but this is discouraged if you intent to submit the app to the store.
you could add the IMP to the class using class_addMethod under a new selector and invoke that selector.
the temporary method can't be removed though.