From f8b98a73a2e8b33c6958fc52e69aa015294e40db Mon Sep 17 00:00:00 2001 From: theraven Date: Sat, 14 Nov 2009 18:09:51 +0000 Subject: [PATCH] Bug fixes in libobjc2: - nil_method now returns 0, not receiver. - Metaclasses actually get their dtables installed with the new ABI. For some reason this wasn't being done, so class messages didn't work with the new ABI. Now they do and (at least some) nontrivial programs work. - Undid commenting out of the code setting the fast ivar access pointers. I can't remember why this was commented out, but it seems not to break anything. I have an LLVM pass that makes compiled code access these pointers, but it's not committed yet. --- init.c | 2 +- nil_method.c | 2 +- sendmsg2.c | 20 +++++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/init.c b/init.c index b59f949..8efb899 100644 --- a/init.c +++ b/init.c @@ -745,7 +745,7 @@ __objc_compute_ivar_offsets (Class class) */ if (CLS_ISNEW_ABI(class)) { - //*(class->ivar_offsets[i]) = ivar->ivar_offset; + *(class->ivar_offsets[i]) = ivar->ivar_offset; } } } diff --git a/nil_method.c b/nil_method.c index c070b0c..1de6e0d 100644 --- a/nil_method.c +++ b/nil_method.c @@ -50,5 +50,5 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see id nil_method (id receiver, SEL op __attribute__ ((__unused__))) { - return receiver; + return 0; } diff --git a/sendmsg2.c b/sendmsg2.c index a51f655..33c0804 100644 --- a/sendmsg2.c +++ b/sendmsg2.c @@ -12,7 +12,7 @@ Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender); // Default implementations of the two new hooks. Return NULL. static id objc_proxy_lookup_null(id receiver, SEL op) { return nil; } -static Slot_t objc_msg_forward3_null(id receiver, SEL op) { return NULL; } +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; Slot_t (*objc_msg_forward3)(id receiver, SEL op) = objc_msg_forward3_null; @@ -24,14 +24,24 @@ Slot_t objc_msg_lookup_internal(id *receiver, SEL selector, id sender) (sidx)selector->sel_id); if (0 == result) { + Class class = (*receiver)->class_pointer; /* Install the dtable if it hasn't already been initialized. */ - if ((*receiver)->class_pointer->dtable == __objc_uninstalled_dtable) + if (dtable_for_class(class) == __objc_uninstalled_dtable) { - objc_mutex_lock(__objc_runtime_mutex); __objc_init_install_dtable (*receiver, selector); - objc_mutex_unlock(__objc_runtime_mutex); - struct sarray *dtable = dtable_for_class((*receiver)->class_pointer); + struct sarray *dtable = dtable_for_class(class); result = sarray_get_safe(dtable, (sidx)selector->sel_id); + if (0 == result) + { + objc_mutex_lock(__objc_runtime_mutex); + if (dtable_for_class(class) == __objc_uninstalled_dtable) + { + __objc_install_dispatch_table_for_class(class); + dtable = dtable_for_class(class); + } + objc_mutex_unlock(__objc_runtime_mutex); + result = sarray_get_safe(class->dtable, (sidx)selector->sel_id); + } } else {