Changeset 5746
- Timestamp:
- Jan 20, 2007, 6:21:48 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/ccl/lib/ffi-darwinppc32.lisp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/lib/ffi-darwinppc32.lisp
r5737 r5746 15 15 ;;; http://opensource.franz.com/preamble.html 16 16 17 (in-package "CCL") 18 19 ;;; If a record type has a single scalar field, return the type 20 ;;; of that field. 21 (defun darwin32::record-type-has-single-scalar-field (record-type) 22 (when (typep record-type 'foreign-structure-type) 23 (ensure-foreign-type-bits record-type) 24 (let* ((fields (foreign-record-type-fields record-type))) 25 (when (null (cdr fields)) 26 (let* ((f0 (car fields)) 27 (type (foreign-record-field-type f0))) 28 (typecase type 29 ((or foreign-record-type foreign-array-type) nil) 30 (otherwise type))))))) 31 32 ;;; If type denotes a foreign record type, return T if it would 33 ;;; be "returned" by passing it as the first argument to the callee. 34 ;;; On DarwinPPC32, this is true of all record types except for 35 ;;; those for which RECORD-TYPE-HAS-SINGLE-SCALAR-FIELD returns 36 ;;; true. 37 (defun darwin32::record-type-returns-structure-as-first-arg (rtype) 38 (when (and rtype 39 (not (typep rtype 'unsigned-byte)) 40 (not (member rtype *foreign-representation-type-keywords* 41 :test #'eq))) 42 (let* ((ftype (if (typep rtype 'foreign-type) 43 rtype 44 (parse-foreign-type rtype)))) 45 (and (typep ftype 'foreign-record-type) 46 (not (darwin32::record-type-has-single-scalar-field ftype)))))) 47 48 49 ;;; Structures that contain a single scalar field are "returned" 50 ;;; as a value with that field's type. 51 ;;; Other structures are "returned" by passing a pointer to a structure 52 ;;; of the appropriate type as the first argument. 53 ;;; Structures that contain a single scalar field are passed by value 54 ;;; by passing the value of that field as a scalar. 55 ;;; Structures that contain more than one field are passed by value 56 ;;; as a sequence of N 32-bit words; %ff-call understands an unsigned 57 ;;; integer argument "type" specifier to denote this. 58 59 (defun darwin32::expand-ff-call (callform args) 60 (let* ((result-type-spec (or (car (last args)) :void)) 61 (enclosing-form nil)) 62 (multiple-value-bind (result-type error) 63 (parse-foreign-type result-type-spec) 64 (if error 65 (setq result-type-spec :void result-type *void-foreign-type*) 66 (setq args (butlast args))) 67 (collect ((argforms)) 68 (when (eq (car args) :monitor-exception-ports) 69 (argforms (pop args))) 70 (when (typep result-type 'foreign-record-type) 71 (let* ((single-scalar (darwin32::record-type-has-single-scalar-field result-type)) 72 (result-form (pop args))) 73 (if single-scalar 74 (progn 75 (setq enclosing-form `(setf ,(%foreign-access-form result-form single-scalar 0 nil)) 76 result-type single-scalar 77 result-type-spec (foreign-type-to-representation-type result-type))) 78 79 (progn 80 (argforms :address) 81 (argforms result-form) 82 (setq result-type *void-foreign-type* 83 result-type-spec :void))))) 84 (unless (evenp (length args)) 85 (error "~s should be an even-length list of alternating foreign types and values" args)) 86 (do* ((args args (cddr args))) 87 ((null args)) 88 (let* ((arg-type-spec (car args)) 89 (arg-value-form (cadr args))) 90 (if (or (member arg-type-spec *foreign-representation-type-keywords* 91 :test #'eq) 92 (typep arg-type-spec 'unsigned-byte)) 93 (progn 94 (argforms arg-type-spec) 95 (argforms arg-value-form)) 96 (let* ((ftype (parse-foreign-type arg-type-spec))) 97 (if (typep ftype 'foreign-record-type) 98 (let* ((single-scalar (darwin32::record-type-has-single-scalar-field ftype))) 99 (if single-scalar 100 (progn 101 (argforms (foreign-type-to-representation-type single-scalar)) 102 (argforms (%foreign-access-form arg-value-form single-scalar 0 nil))) 103 (let* ((bits (ensure-foreign-type-bits ftype))) 104 (argforms (ceiling bits 32)) 105 (argforms arg-value-form)))) 106 (progn 107 (argforms (foreign-type-to-representation-type ftype)) 108 (argforms arg-value-form))))))) 109 (argforms (foreign-type-to-representation-type result-type)) 110 (let* ((call `(,@callform ,@(argforms)))) 111 (if enclosing-form 112 `(,@enclosing-form ,call) 113 call)))))) 114 115 116 117
Note:
See TracChangeset
for help on using the changeset viewer.
