used with any Objective-C object • Responds to all selectors that original object's superclass instances respond to • Keeps reference to the original object
value and arguments • Encodings are implementation detail • Create by concatenating results of @encode directive • Get existing from method_getTypeEncoding()
• Original object is accessible through proxy instance • Method resolution is on class level ➡ Need to “encode” original object's class into proxy's class
class • Embed original object's class name as part of proxy's subclass name • Alloc/init proxy subclass During proxy creation During method resolution • Retrieve original object's class from proxy subclass name • Obtain method signature through original object's class
• Receives selector and all other arguments • Should get objc_super from self • Should call objc_msgSendSuper() or objc_msgSendSuper_stret() • Should pass all other arguments verbatim • Should return result
• different CPUs — different rules for returning results • result *usually* returned in some register • registers have fixed size • structures can have arbitrary size ➡ large structures won't fit into registers
pushes onto the stack • Call == push next instruction address + unconditional jump • Control is transferred to called function • Callee retrieves arguments from registers and/or stack • Callee does something useful • Return == pop return address from stack + unconditional jump
correct locations • Almost all • Replace proxy instance address in x0 with the address of objc_super ivar • objc_super is at a fixed offset from self • Offset can be retrieved from Objective-C runtime • Tail call to objc_msgSendSuper()
last instruction and return value of the called function is also the return value of the current one • Call → jump • Stack frame is reused • Control will be returned directly to the function that called the current function • Current function symbol will be missing from stack trace • Clang does this all the time