- (defclass ginstance (proxy)
- ((class :allocation :alien :type pointer))
- (:metaclass proxy-class)))
-
-(defun %type-of-ginstance (location)
- (let ((class (sap-ref-sap location 0)))
- (type-from-number (sap-ref-unsigned class 0))))
-
-(deftype-method translate-from-alien
- ginstance (type-spec location &optional weak-ref)
- (declare (ignore type-spec))
- `(let ((location ,location))
- (unless (null-pointer-p location)
- (ensure-proxy-instance
- (%type-of-ginstance location) location ,weak-ref))))
+ (defvar *type-initializers* ())
+ (defun %find-types-in-library (pathname prefixes ignore)
+ (let ((process (run-program
+ "/usr/bin/nm" (list "--defined-only" "-D" (namestring (truename pathname)))
+ :output :stream :wait nil)))
+ (unwind-protect
+ (loop
+ as symbol = (let ((line (read-line (process-output process) nil)))
+ (when line (subseq line 11)))
+ while symbol
+ when (and
+ (> (length symbol) 9)
+ (or
+ (not prefixes)
+ (some #'(lambda (prefix)
+ (and
+ (> (length symbol) (length prefix))
+ (string= prefix symbol :end2 (length prefix))))
+ (mklist prefixes)))
+ (string= "_get_type" symbol :start2 (- (length symbol) 9))
+ (not (member symbol ignore :test #'string=)))
+ collect symbol)
+ (process-close process)))))
+
+
+(defmacro init-types-in-library (filename &key prefix ignore)
+ (let ((names (%find-types-in-library filename prefix ignore)))
+ `(progn
+ ,@(mapcar #'(lambda (name)
+ `(progn
+ (defbinding (,(intern name) ,name) () type-number)
+ (,(intern name))
+ (pushnew ',(intern name) *type-initializers*)))
+ names))))
+
+(defun find-type-init-function (type-number)
+ (loop
+ for type-init in *type-initializers*
+ when (= type-number (funcall type-init))
+ do (return type-init)))
+
+(defun register-type-as (type-number)
+ (or
+ (find-type-init-function type-number)
+ (find-foreign-type-name type-number)
+ (error "Unknown type-number: ~A" type-number)))
+
+(defun default-type-init-name (type)
+ (find-symbol (format nil "~A_~A_get_type"
+ (package-prefix *package*)
+ (substitute #\_ #\- (string-downcase type)))))