mirror of
https://github.com/darlinghq/darling-libobjc2.git
synced 2025-03-03 06:06:05 +00:00
Added a hook that defines the behaviour when you call a method with the wrong signature.
This commit is contained in:
parent
06015757a7
commit
0284155f2d
@ -56,3 +56,11 @@ OBJC_HOOK void (*_objc_unexpected_exception)(id exception);
|
|||||||
* to
|
* to
|
||||||
*/
|
*/
|
||||||
OBJC_HOOK Class (*_objc_class_for_boxing_foreign_exception)(int64_t exceptionClass);
|
OBJC_HOOK Class (*_objc_class_for_boxing_foreign_exception)(int64_t exceptionClass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook called when selector type does not match the method type in the
|
||||||
|
* receiver. This should return the slot to use instead, although it may throw
|
||||||
|
* an exception or perform some other action.
|
||||||
|
*/
|
||||||
|
extern struct objc_slot* (*_objc_selector_type_mismatch)(Class cls,
|
||||||
|
SEL selector, struct objc_slot *result);
|
||||||
|
@ -54,8 +54,6 @@ inline static BOOL isSelRegistered(SEL sel)
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TYPE_DEPENDENT_DISPATCH
|
|
||||||
/**
|
/**
|
||||||
* Skip anything in a type encoding that is irrelevant to the comparison
|
* Skip anything in a type encoding that is irrelevant to the comparison
|
||||||
* between selectors, including type qualifiers and argframe info.
|
* between selectors, including type qualifiers and argframe info.
|
||||||
@ -90,6 +88,8 @@ static BOOL selector_types_equal(const char *t1, const char *t2)
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TYPE_DEPENDENT_DISPATCH
|
||||||
|
|
||||||
static BOOL selector_types_equivalent(const char *t1, const char *t2)
|
static BOOL selector_types_equivalent(const char *t1, const char *t2)
|
||||||
{
|
{
|
||||||
// We always treat untyped selectors as having the same type as typed
|
// We always treat untyped selectors as having the same type as typed
|
||||||
@ -202,7 +202,6 @@ static inline void add_selector_to_table(SEL aSel, int32_t uid, uint32_t idx)
|
|||||||
static inline void register_selector_locked(SEL aSel)
|
static inline void register_selector_locked(SEL aSel)
|
||||||
{
|
{
|
||||||
uintptr_t idx = selector_count++;
|
uintptr_t idx = selector_count++;
|
||||||
SEL original = selector_lookup(aSel->name, 0);
|
|
||||||
if (NULL == aSel->types)
|
if (NULL == aSel->types)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Registering selector %d %s\n", idx, sel_getName(aSel));
|
fprintf(stderr, "Registering selector %d %s\n", idx, sel_getName(aSel));
|
||||||
|
29
sendmsg2.c
29
sendmsg2.c
@ -27,6 +27,20 @@ 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 struct objc_slot* objc_selector_type_mismatch(Class cls, SEL
|
||||||
|
selector, Slot_t result)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Calling [%s %c%s] with incorrect signature. "
|
||||||
|
"Method has %s, selector has %s\n",
|
||||||
|
cls->name,
|
||||||
|
class_isMetaClass(cls) ? '+' : '-',
|
||||||
|
sel_getName(selector),
|
||||||
|
result->types,
|
||||||
|
sel_getType_np(selector));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
struct objc_slot* (*_objc_selector_type_mismatch)(Class cls, SEL
|
||||||
|
selector, struct objc_slot *result) = objc_selector_type_mismatch;
|
||||||
static
|
static
|
||||||
// Uncomment for debugging
|
// Uncomment for debugging
|
||||||
//__attribute__((noinline))
|
//__attribute__((noinline))
|
||||||
@ -66,12 +80,8 @@ retry:;
|
|||||||
}
|
}
|
||||||
if ((result = objc_dtable_lookup(dtable, get_untyped_idx(selector))))
|
if ((result = objc_dtable_lookup(dtable, get_untyped_idx(selector))))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Calling %s with incorrect signature. "
|
return _objc_selector_type_mismatch((*receiver)->isa, selector,
|
||||||
"Method has %s, selector has %s\n",
|
result);
|
||||||
sel_getName(selector),
|
|
||||||
result->types,
|
|
||||||
sel_getType_np(selector));
|
|
||||||
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
|
// If some other library wants us to play forwarding games, try
|
||||||
@ -265,12 +275,7 @@ Slot_t objc_get_slot(Class cls, SEL selector)
|
|||||||
}
|
}
|
||||||
if ((result = objc_dtable_lookup(dtable, get_untyped_idx(selector))))
|
if ((result = objc_dtable_lookup(dtable, get_untyped_idx(selector))))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Calling %s with incorrect signature. "
|
return _objc_selector_type_mismatch(cls, selector, result);
|
||||||
"Method has %s, selector has %s\n",
|
|
||||||
sel_getName(selector),
|
|
||||||
result->types,
|
|
||||||
sel_getType_np(selector));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user