(defstruct (alien-type-class (:copier nil))
(name nil :type symbol)
+ (defstruct-name nil :type symbol)
(include nil :type (or null alien-type-class))
(unparse nil :type (or null function))
(type= nil :type (or null function))
(or (gethash name *alien-type-classes*)
(error "no alien type class ~S" name)))
-(defun create-alien-type-class-if-necessary (name include)
+(defun create-alien-type-class-if-necessary (name defstruct-name include)
(let ((old (gethash name *alien-type-classes*))
(include (and include (alien-type-class-or-lose include))))
(if old
(setf (alien-type-class-include old) include)
(setf (gethash name *alien-type-classes*)
- (make-alien-type-class :name name :include include)))))
+ (make-alien-type-class :name name
+ :defstruct-name defstruct-name
+ :include include)))))
(defparameter *method-slot-alist*
'((:unparse . alien-type-class-unparse)
(symbol
(values
include
- (symbolicate "ALIEN-" include "-TYPE")
+ (alien-type-class-defstruct-name
+ (alien-type-class-or-lose include))
nil))
(list
(values
(car include)
- (symbolicate "ALIEN-" (car include) "-TYPE")
+ (alien-type-class-defstruct-name
+ (alien-type-class-or-lose (car include)))
(cdr include))))
`(progn
(eval-when (:compile-toplevel :load-toplevel :execute)
- (create-alien-type-class-if-necessary ',name ',(or include 'root)))
+ (create-alien-type-class-if-necessary ',name ',defstruct-name
+ ',(or include 'root)))
(def!struct (,defstruct-name
(:include ,include-defstruct
(class ',name)
(eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
(defun auxiliary-type-definitions (env)
(multiple-value-bind (result expanded-p)
- (sb!xc:macroexpand '&auxiliary-type-definitions& env)
+ (%macroexpand '&auxiliary-type-definitions& env)
(if expanded-p
result
;; This is like having the global symbol-macro definition be
;;;; the root alien type
(eval-when (:compile-toplevel :load-toplevel :execute)
- (create-alien-type-class-if-necessary 'root nil))
+ (create-alien-type-class-if-necessary 'root 'alien-type nil))
(def!struct (alien-type
(:make-load-form-fun sb!kernel:just-dump-it-normally)
(declare (ignore type))
'system-area-pointer)
-(define-alien-type-method (system-area-pointer :alien-rep) (type)
- (declare (ignore type))
+(define-alien-type-method (system-area-pointer :alien-rep) (type context)
+ (declare (ignore type context))
'system-area-pointer)
(define-alien-type-method (system-area-pointer :naturalize-gen) (type alien)
(def!macro maybe-with-pinned-objects (variables types &body body)
(declare (ignorable variables types))
(let ((pin-variables
- ;; Only pin things on x86/x86-64, since on non-conservative
- ;; gcs it'd imply disabling the GC. Which is something we
- ;; don't want to do every time we're calling to C.
- #!+(or x86 x86-64)
+ ;; Only pin things on GENCGC, since on CHENEYGC it'd imply
+ ;; disabling the GC. Which is something we don't want to do
+ ;; every time we're calling to C.
+ #!+gencgc
(loop for variable in variables
for type in types
when (invoke-alien-type-method :deport-pin-p type)
(defun compute-lisp-rep-type (type)
(invoke-alien-type-method :lisp-rep type))
-(defun compute-alien-rep-type (type)
- (invoke-alien-type-method :alien-rep type))
+;;; CONTEXT is either :NORMAL (the default) or :RESULT (alien function
+;;; return values). See the :ALIEN-REP method for INTEGER for
+;;; details.
+(defun compute-alien-rep-type (type &optional (context :normal))
+ (invoke-alien-type-method :alien-rep type context))
\f
;;;; default methods
(declare (ignore type))
nil)
-(define-alien-type-method (root :alien-rep) (type)
- (declare (ignore type))
+(define-alien-type-method (root :alien-rep) (type context)
+ (declare (ignore type context))
'*)
(define-alien-type-method (root :naturalize-gen) (type alien)
(list (if (alien-integer-type-signed type) 'signed-byte 'unsigned-byte)
(alien-integer-type-bits type)))
-(define-alien-type-method (integer :alien-rep) (type)
- (list (if (alien-integer-type-signed type) 'signed-byte 'unsigned-byte)
- (alien-integer-type-bits type)))
-
+(define-alien-type-method (integer :alien-rep) (type context)
+ ;; When returning integer values that are narrower than a machine
+ ;; register from a function, some platforms leave the higher bits of
+ ;; the register uninitialized. On those platforms, we use an
+ ;; alien-rep of the full register width when checking for purposes
+ ;; of return values and override the naturalize method to perform
+ ;; the sign extension (in compiler/target/c-call.lisp).
+ (ecase context
+ ((:normal #!-(or x86 x86-64) :result)
+ (list (if (alien-integer-type-signed type) 'signed-byte 'unsigned-byte)
+ (alien-integer-type-bits type)))
+ #!+(or x86 x86-64)
+ (:result
+ (list (if (alien-integer-type-signed type) 'signed-byte 'unsigned-byte)
+ sb!vm:n-word-bits))))
+
+;;; As per the comment in the :ALIEN-REP method above, this is defined
+;;; elsewhere for x86oids.
+#!-(or x86 x86-64)
(define-alien-type-method (integer :naturalize-gen) (type alien)
(declare (ignore type))
alien)
(define-alien-type-method (float :lisp-rep) (type)
(alien-float-type-type type))
-(define-alien-type-method (float :alien-rep) (type)
+(define-alien-type-method (float :alien-rep) (type context)
+ (declare (ignore context))
(alien-float-type-type type))
(define-alien-type-method (float :naturalize-gen) (type alien)
#!+sb-doc
"Return an Alien pointer to the data addressed by Expr, which must be a call
to SLOT or DEREF, or a reference to an Alien variable."
- (let ((form (sb!xc:macroexpand expr env)))
+ (let ((form (%macroexpand expr env)))
(or (typecase form
(cons
(case (car form)