+ ,@(mapcar
+ #'(lambda (name)
+ `(progn
+ (defbinding (,(intern name) ,name) () type-number)
+ (,(intern name))
+ (pushnew (cons ',(intern name) ,filename) *type-initializers*
+ :test #'car-eq-p)))
+ 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)))))
+
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defclass type-info (struct)
+ ((class-size :allocation :alien :type (unsigned 16) :initarg :class-size)
+ (base-init :allocation :alien :type pointer)
+ (base-finalize :allocation :alien :type pointer)
+ (class-init :allocation :alien :type pointer)
+ (class-finalize :allocation :alien :type pointer)
+ (class-data :allocation :alien :type pointer)
+ (instance-size :allocation :alien :type (unsigned 16)
+ :initarg :instance-size)
+ (n-preallocs :allocation :alien :type (unsigned 16))
+ (instance-init :allocation :alien :type pointer)
+ (value-table :allocation :alien :type pointer))
+ (:metaclass struct-class)))
+
+(defbinding %type-register-static () type-number
+ (parent-type type-number)
+ (name string)
+ (info type-info)
+ (0 unsigned-int))
+
+(defun register-new-type (type parent &optional foreign-name)
+ (let ((parent-info (type-query parent)))
+ (with-slots ((parent-number type-number) class-size instance-size) parent-info
+ (let ((type-number
+ (%type-register-static
+ parent-number
+ (or foreign-name (default-alien-type-name type))
+ (make-instance 'type-info :class-size class-size :instance-size instance-size))))
+ (pushnew (list type parent foreign-name) *registered-static-types* :key #'car)
+ (setf (gethash type *lisp-type-to-type-number*) type-number)
+ (setf (gethash type-number *type-number-to-lisp-type*) type)
+ type-number))))