From 0a587207161a7f5d556c1f8a165938770f73fd78 Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Mon, 18 Feb 2008 23:08:35 +0100 Subject: Fix Objective-C class registration. darcs-hash:03e58bd27621a0bf46f05cc1ee733da1c7ab1170 --- Lisp/class-definition.lisp | 3 +- Lisp/tests.lisp | 10 ++++++- Objective-C/libobjcl.h | 8 ++++++ Objective-C/libobjcl.m | 70 +++++++++++++++++++++++++++++++++------------- 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/Lisp/class-definition.lisp b/Lisp/class-definition.lisp index ff091a9..6ecb189 100644 --- a/Lisp/class-definition.lisp +++ b/Lisp/class-definition.lisp @@ -340,7 +340,7 @@ (defmethod make-instance :before ((class objective-c-class) &key &allow-other-keys) - (unless (typep class 'objective-c-meta-class) + (unless (subtypep class 'objective-c-meta-class) (foreign-class-ensure-registered class))) @@ -348,6 +348,7 @@ (with-exclusive-access (class) (unless (foreign-class-registered-p class) (setf (foreign-class-registered-p class) t) + (%objcl-finalise-class (pointer-to (class-of class))) (%objcl-finalise-class (pointer-to class)))) class) diff --git a/Lisp/tests.lisp b/Lisp/tests.lisp index 443929e..d2d89c9 100644 --- a/Lisp/tests.lisp +++ b/Lisp/tests.lisp @@ -25,7 +25,8 @@ #:bit-field #:opaque #:bycopy #:byref #:primitive-invoke #:print-typespec-to-string #:nominally #:find-objc-meta-class - #:objcl-object-backed-by-lisp-class-p)) + #:objcl-object-backed-by-lisp-class-p + #:foreign-class-registered-p)) (in-package #:mulk.objective-cl.tests) (in-root-suite) @@ -368,10 +369,17 @@ :foreign-type (:int ()))) :metaclass (find-objc-meta-class "NSObject")))) + ;; Class initialisation. + (is (not (foreign-class-registered-p class))) + ;; Sanity checks. (is (typep class 'objective-c-class)) (setq instance (is (invoke (invoke class 'alloc) 'init))) + ;; Class finalisation. (Should be automatic upon instance + ;; creation.) + (is (foreign-class-registered-p class)) + ;; Object identity preservation. (is (eql instance (invoke instance 'self))) diff --git a/Objective-C/libobjcl.h b/Objective-C/libobjcl.h index bda201b..e7194a5 100644 --- a/Objective-C/libobjcl.h +++ b/Objective-C/libobjcl.h @@ -46,6 +46,14 @@ typedef struct objc_ivar *IVAR_T; #endif +struct ObjCLMethod +{ + SEL method_name; + char *signature; + IMP imp; +}; + + extern NSException *objcl_oom_exception; extern id objcl_current_exception; extern NSRecursiveLock *objcl_current_exception_lock; diff --git a/Objective-C/libobjcl.m b/Objective-C/libobjcl.m index 499c9ae..9531052 100644 --- a/Objective-C/libobjcl.m +++ b/Objective-C/libobjcl.m @@ -755,8 +755,7 @@ objcl_create_class (const char *class_name, TRACE (@"ObjcUtilities_new_class end"); NSString *ns_class_name = [NSString stringWithUTF8String: class_name]; - [method_lists setObject: - [NSValue valueWithPointer: ObjcUtilities_alloc_method_list] + [method_lists setObject: [NSValue valueWithPointer: nil] forKey: ns_class_name]; [method_list_lengths setObject: [NSNumber numberWithInt: 0] forKey: ns_class_name]; @@ -782,18 +781,26 @@ objcl_add_method (Class class, #ifdef __NEXT_RUNTIME__ preclass_addMethod (class, method_name, imp, signature); #else - NSString *class_name = [NSString stringWithUTF8String: objcl_class_name (class)]; - MethodList *method_list = [[method_lists objectForKey: class_name] pointerValue]; - int index = [[method_list_lengths objectForKey: class_name] intValue]; - - ObjcUtilities_insert_method_in_list - (method_list, - index, - objcl_selector_name (method_name), - ObjcUtilities_build_runtime_Objc_signature (signature), - imp); - - [method_list_lengths setObject: [NSNumber numberWithInt: index] + NSString *class_name; + struct ObjCLMethod **methods; + int index; + + class_name = [NSString stringWithUTF8String: objcl_class_name (class)]; + index = [[method_list_lengths objectForKey: class_name] intValue]; + methods = [[method_lists objectForKey: class_name] pointerValue]; + + methods = realloc (methods, (index + 1) * sizeof (struct ObjCLMethod *)); + methods[index] = malloc (sizeof (struct ObjCLMethod)); + + methods[index]->signature = malloc (strlen (signature) + 1); + + methods[index]->method_name = method_name; + strcpy (methods[index]->signature, signature); + methods[index]->imp = imp; + + [method_lists setObject: [NSValue valueWithPointer: methods] + forKey: class_name]; + [method_list_lengths setObject: [NSNumber numberWithInt: (index + 1)] forKey: class_name]; #endif } @@ -806,11 +813,36 @@ objcl_finalise_class (Class class) /* FIXME: Should we do this if class is a metaclass? */ objc_registerClassPair (class); #else - NSString *class_name = [NSString stringWithUTF8String: - objcl_class_name (class)]; - ObjcUtilities_register_method_list - (class, [[method_lists objectForKey: class_name] - pointerValue]); + int i; + int method_count; + NSString *class_name; + MethodList *method_list; + struct ObjCLMethod **methods; + + class_name = [NSString stringWithUTF8String: objcl_class_name (class)]; + methods = [[method_lists objectForKey: class_name] pointerValue]; + + if (methods) + { + method_list = ObjcUtilities_alloc_method_list (method_count); + method_count = [[method_list_lengths objectForKey: class_name] intValue]; + + for (i = 0; i < method_count; i++) + { + ObjcUtilities_insert_method_in_list + (method_list, + i, + objcl_selector_name (methods[i]->method_name), + ObjcUtilities_build_runtime_Objc_signature (methods[i]->signature), + methods[i]->imp); + + free (methods[i]->signature); + free (methods[i]); + } + + free (methods); + ObjcUtilities_register_method_list (class, method_list); + } [method_lists removeObjectForKey: class_name]; [method_list_lengths removeObjectForKey: class_name]; -- cgit v1.2.3