summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lisp/defpackage.lisp1
-rw-r--r--Lisp/libobjcl.lisp26
-rw-r--r--Lisp/method-definition.lisp6
-rw-r--r--Lisp/reader-syntax.lisp2
-rw-r--r--Objective-C/libobjcl.m48
5 files changed, 80 insertions, 3 deletions
diff --git a/Lisp/defpackage.lisp b/Lisp/defpackage.lisp
index 3cacf12..da289ee 100644
--- a/Lisp/defpackage.lisp
+++ b/Lisp/defpackage.lisp
@@ -39,6 +39,7 @@
#:define-returns-boolean-exception
#:undefine-returns-boolean-exception
#:collect-classes
+ #:collect-methods
;; Generic functions
#:objc-eql
diff --git a/Lisp/libobjcl.lisp b/Lisp/libobjcl.lisp
index d038c62..af8b66c 100644
--- a/Lisp/libobjcl.lisp
+++ b/Lisp/libobjcl.lisp
@@ -196,6 +196,13 @@
(defcfun ("objcl_test_foo" objcl-test-foo) :void)
+(defcfun ("objcl_method_selector" %objcl-method-selector) :pointer
+ (method :pointer))
+
+(defcfun ("objcl_class_methods" %objcl-class-methods) :pointer
+ (class :pointer)
+ (count-out :pointer))
+
(defcvar *objcl-current-exception-lock* :pointer)
(defcvar *objcl-current-exception* :pointer)
@@ -920,6 +927,25 @@ separating parts by hyphens works nicely in all of the `:INVERT`,
(not (zerop (%objcl-objc2-p))))
+;;;; (@* "Registry update and maintenance")
+(defcallback collect-class-methods :void ((class :pointer))
+ (flet ((collect-methods (class)
+ (with-foreign-object (count-buf :unsigned-int)
+ (let ((method-array (%objcl-class-methods class count-buf)))
+ (unwind-protect
+ (dotimes (i (mem-ref count-buf :unsigned-int))
+ (intern-pointer-wrapper 'selector
+ :pointer
+ (%objcl-method-selector
+ (mem-aref method-array :void i))))
+ (foreign-free method-array))))))
+ (collect-methods class)
+ (collect-methods (%objcl-class-metaclass class))))
+
+(defun collect-methods ()
+ (%objcl-for-each-class-do (callback collect-class-methods)))
+
+
;;;; (@* "Slot access")
(defun objcl-slot-type (slot)
(%objcl-slot-type slot))
diff --git a/Lisp/method-definition.lisp b/Lisp/method-definition.lisp
index 41f1f84..cbfc344 100644
--- a/Lisp/method-definition.lisp
+++ b/Lisp/method-definition.lisp
@@ -69,7 +69,8 @@
else
collect :id into type-specifiers
finally (return
- `(defmethod ,name
+ `(defmethod ,(intern (symbol-name name)
+ '#:objective-c-methods)
argtypes-start ,@type-specifiers argtypes-end
,@qualifiers ,lambda-list
,@body)))))))
@@ -80,7 +81,8 @@
(defmacro define-objective-c-generic-function (name lambda-list &body options)
- `(defgeneric ,name ,lambda-list
+ `(defgeneric ,(intern (symbol-name name) '#:objective-c-methods)
+ ,lambda-list
,@(unless (position :generic-function-class
options
:key #'car)
diff --git a/Lisp/reader-syntax.lisp b/Lisp/reader-syntax.lisp
index 9f0bcb7..ddf9edc 100644
--- a/Lisp/reader-syntax.lisp
+++ b/Lisp/reader-syntax.lisp
@@ -78,7 +78,7 @@ Method __selector__s have to be interned prior to use. As this reader
macro is not capable of interning new __selector__s, you have to ensure
that __intern-selector__ is called before the respective __selector__ is
used. This is not a problem for __selector__s known at load-time nor for
-__selector__s registered by way of __collect-selectors__.
+__selector__s registered by way of __collect-methods__.
## See also:
diff --git a/Objective-C/libobjcl.m b/Objective-C/libobjcl.m
index d32a37c..0b1719f 100644
--- a/Objective-C/libobjcl.m
+++ b/Objective-C/libobjcl.m
@@ -1053,6 +1053,54 @@ objcl_for_each_class_do (void (*function) (Class))
}
+void **
+objcl_class_methods (Class class, unsigned int *count)
+{
+#ifdef __NEXT_RUNTIME__
+ return (void **) class_copyMethodList (class, count);
+#else
+ size_t buflen = 0;
+ void **buf = NULL;
+ MethodList_t list = class->methods;
+
+ *count = 0;
+
+ while (list)
+ {
+ int i;
+ unsigned int position = *count;
+ *count += list->method_count;
+
+ if (buflen < *count)
+ {
+ buflen = *count;
+ buf = realloc (buf, buflen * sizeof (void *));
+ }
+
+ for (i = 0; i < list->method_count; i++)
+ {
+ buf[position + i] = &list->method_list[i];
+ }
+
+ list = list->method_next;
+ }
+
+ return buf;
+#endif
+}
+
+
+SEL
+objcl_method_selector (void *method)
+{
+#ifdef __NEXT_RUNTIME__
+ return method_getName ((Method) method);
+#else
+ return ((Method_t) method)->method_name;
+#endif
+}
+
+
/* The function objcl_test_foo is a general-purpose debugging tool that
can be adapted as needed. */
@interface MLKTestStringHelper