Fix message forwarding by, for example, actually calling the public forwarding hook, instead of one that isn't exposed to GNUstep...

main
theraven 16 years ago
parent a75064866a
commit 2cc96a6f7e

@ -26,13 +26,13 @@ OBJC_HOOK void (*_objc_load_callback)(Class cls, struct objc_category *category)
* The hook used for fast proxy lookups. This takes an object and a selector * The hook used for fast proxy lookups. This takes an object and a selector
* and returns the instance that the message should be forwarded to. * and returns the instance that the message should be forwarded to.
*/ */
OBJC_HOOK id (*objc_proxy_lookup)(id receiver, SEL op); extern id (*objc_proxy_lookup)(id receiver, SEL op);
/** /**
* New runtime forwarding hook. This might be removed in future - it's * New runtime forwarding hook. This might be removed in future - it's
* actually no more expressive than the forward2 hook and forces Foundation to * actually no more expressive than the forward2 hook and forces Foundation to
* do some stuff that the runtime is better suited to. * do some stuff that the runtime is better suited to.
*/ */
OBJC_HOOK struct objc_slot *(*__objc_msg_forward3)(id, SEL); extern struct objc_slot *(*__objc_msg_forward3)(id, SEL);
/** /**
* Forwarding hook. Takes an object and a selector and returns a method that * Forwarding hook. Takes an object and a selector and returns a method that
* handles the forwarding. * handles the forwarding.

@ -25,11 +25,15 @@ static id objc_proxy_lookup_null(id receiver, SEL op) { return nil; }
static Slot_t objc_msg_forward3_null(id receiver, SEL op) { return &nil_slot; } static Slot_t objc_msg_forward3_null(id receiver, SEL op) { return &nil_slot; }
id (*objc_proxy_lookup)(id receiver, SEL op) = objc_proxy_lookup_null; id (*objc_proxy_lookup)(id receiver, SEL op) = objc_proxy_lookup_null;
Slot_t (*objc_msg_forward3)(id receiver, SEL op) = objc_msg_forward3_null; Slot_t (*__objc_msg_forward3)(id receiver, SEL op) = objc_msg_forward3_null;
static inline Slot_t objc_msg_lookup_internal(id *receiver, static
SEL selector, // Uncomment for debugging
id sender) //__attribute__((noinline))
__attribute__((always_inline))
Slot_t objc_msg_lookup_internal(id *receiver,
SEL selector,
id sender)
{ {
Slot_t result = SparseArrayLookup((*receiver)->isa->dtable, Slot_t result = SparseArrayLookup((*receiver)->isa->dtable,
PTR_TO_IDX(selector->name)); PTR_TO_IDX(selector->name));
@ -62,8 +66,8 @@ static inline Slot_t objc_msg_lookup_internal(id *receiver,
return result; return result;
} }
id newReceiver = objc_proxy_lookup(*receiver, selector); id newReceiver = objc_proxy_lookup(*receiver, selector);
// If some other library wants us to play forwarding games, try again // If some other library wants us to play forwarding games, try
// with the new object. // again with the new object.
if (nil != newReceiver) if (nil != newReceiver)
{ {
*receiver = newReceiver; *receiver = newReceiver;
@ -71,7 +75,7 @@ static inline Slot_t objc_msg_lookup_internal(id *receiver,
} }
if (0 == result) if (0 == result)
{ {
result = objc_msg_forward3(*receiver, selector); result = __objc_msg_forward3(*receiver, selector);
} }
} }
} }
@ -299,9 +303,7 @@ IMP objc_msg_lookup(id receiver, SEL selector)
Slot_t slot = objc_msg_lookup_internal(&self, selector, nil); Slot_t slot = objc_msg_lookup_internal(&self, selector, nil);
if (self != receiver) if (self != receiver)
{ {
if (0 == __objc_msg_forward2) { return 0; } slot = __objc_msg_forward3(receiver, selector);
return __objc_msg_forward2(receiver, selector);
} }
return slot->method; return slot->method;
} }

Loading…
Cancel
Save