X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fhost-alieneval.lisp;h=85859ab18abf71ba2939a326de1ef7581d93fb80;hb=65b5ab7e713d04e0d76bc0ee196374f6e57b922f;hp=267a652d77995841937ce504133ebc7b5386fe90;hpb=2ff7f7e72730bd5c43f259b7ecf094fbd75ef294;p=sbcl.git diff --git a/src/code/host-alieneval.lisp b/src/code/host-alieneval.lisp index 267a652..85859ab 100644 --- a/src/code/host-alieneval.lisp +++ b/src/code/host-alieneval.lisp @@ -34,6 +34,7 @@ (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)) @@ -57,13 +58,15 @@ (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) @@ -99,16 +102,19 @@ (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) @@ -329,7 +335,7 @@ ;;;; 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) @@ -358,8 +364,8 @@ (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) @@ -496,8 +502,11 @@ (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)) ;;;; default methods @@ -515,8 +524,8 @@ (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) @@ -582,10 +591,25 @@ (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) @@ -781,7 +805,8 @@ (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)