summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lisp/class-definition.lisp3
-rw-r--r--Lisp/tests.lisp10
-rw-r--r--Objective-C/libobjcl.h8
-rw-r--r--Objective-C/libobjcl.m70
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];