Changeset 5805


Ignore:
Timestamp:
Jan 29, 2007, 1:33:22 AM (18 years ago)
Author:
Gary Byers
Message:

Flesh out the new callback stuff.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lib/ffi-darwinppc32.lisp

    r5759 r5805  
    2020;;; of that field.
    2121(defun darwin32::record-type-has-single-scalar-field (record-type)
    22   (when (typep record-type 'foreign-structure-type)
     22  (when (eq (foreign-record-type-kind record-type) :struct)
    2323    (ensure-foreign-type-bits record-type)
    2424    (let* ((fields (foreign-record-type-fields record-type)))
     
    115115           
    116116           
    117                          
     117;;; Return 7 values:
     118;;; A list of RLET bindings
     119;;; A list of LET* bindings
     120;;; A list of DYNAMIC-EXTENT declarations for the LET* bindings
     121;;; A list of initializaton forms for (some) structure args
     122;;; A FOREIGN-TYPE representing the "actual" return type.
     123;;; A form which can be used to initialize FP-ARGS-PTR, relative
     124;;;  to STACK-PTR.  (This is unused on linuxppc32.)
     125;;; The byte offset of the foreign return address, relative to STACK-PTR
     126
     127(defun darwin32::generate-callback-bindings (stack-ptr fp-args-ptr argvars argspecs result-spec struct-result-name)
     128  (collect ((lets)
     129            (rlets)
     130            (inits)
     131            (dynamic-extent-names))
     132    (let* ((rtype (parse-foreign-type result-spec))
     133           (fp-regs-form nil))
     134      (flet ((set-fp-regs-form ()
     135               (unless fp-regs-form
     136                 (setq fp-regs-form `(%get-ptr ,stack-ptr ,(- ppc32::c-frame.unused-1 ppc32::c-frame.param0))))))
     137        (when (typep rtype 'foreign-record-type)
     138          (if (darwin32::record-type-has-single-scalar-field rtype)
     139            (rlets (list struct-result-name (foreign-record-type-name rtype)))
     140            (setq argvars (cons struct-result-name argvars)
     141                  argspecs (cons :address argspecs)
     142                  rtype *void-foreign-type*)))
     143        (when (typep rtype 'foreign-float-type)
     144          (set-fp-regs-form))
     145        (do* ((argvars argvars (cdr argvars))
     146              (argspecs argspecs (cdr argspecs))
     147              (fp-arg-num 0)
     148              (offset 0 (+ offset delta))
     149              (delta 4 4)
     150              (bias 0 0)
     151              (use-fp-args nil nil))
     152             ((null argvars)
     153              (values (rlets) (lets) (dynamic-extent-names) (inits) rtype fp-regs-form (- ppc32::c-frame.savelr ppc32::c-frame.param0)))
     154          (flet ((next-scalar-arg (argtype)
     155                   `(,(cond
     156                       ((typep argtype 'foreign-single-float-type)
     157                        (if (< (incf fp-arg-num) 14)
     158                          (progn
     159                            (setq use-fp-args t)
     160                            '%get-single-float-from-double-ptr)
     161                          (progn
     162                            '%get-single-float)))
     163                       ((typep argtype 'foreign-double-float-type)
     164                        (setq delta 8)
     165                        (if (< (incf fp-arg-num) 14)
     166                          (setq use-fp-args t))
     167                        '%get-double-float)
     168                       ((and (typep argtype 'foreign-integer-type)
     169                             (= (foreign-integer-type-bits argtype) 64)
     170                             (foreign-integer-type-signed argtype))
     171                        (setq delta 8)
     172                        '%%get-signed-longlong)
     173                       ((and (typep argtype 'foreign-integer-type)
     174                             (= (foreign-integer-type-bits argtype) 64)
     175                             (not (foreign-integer-type-signed argtype)))
     176                        (setq delta 8)
     177                        '%%get-unsigned-longlong)
     178                       ((or (typep argtype 'foreign-pointer-type)
     179                            (typep argtype 'foreign-array-type))
     180                        '%get-ptr)
     181                       (t
     182                        (cond ((typep argtype 'foreign-integer-type)
     183                               (let* ((bits (foreign-integer-type-bits argtype))
     184                                      (signed (foreign-integer-type-signed argtype)))
     185                                 (cond ((<= bits 8)
     186                                        (setq bias 3)
     187                                        (if signed
     188                                          '%get-signed-byte '
     189                                          '%get-unsigned-byte))
     190                                       ((<= bits 16)
     191                                        (setq bias 2)
     192                                        (if signed
     193                                          '%get-signed-word
     194                                          '%get-unsigned-word))
     195                                       ((<= bits 32)
     196                                        (if signed
     197                                          '%get-signed-long
     198                                          '%get-unsigned-long))
     199                                       (t
     200                                        (error "Don't know how to access foreign argument of type ~s" (unparse-foreign-type argtype))))))
     201                              (t
     202                               (error "Don't know how to access foreign argument of type ~s" (unparse-foreign-type argtype))))))
     203                     ,(if use-fp-args fp-args-ptr stack-ptr)
     204                     ,(if use-fp-args (* 8 (1- fp-arg-num))
     205                          `(+ ,offset ,bias)))))                   
     206          (let* ((name (car argvars))
     207                 (spec (car argspecs))
     208                 (argtype (parse-foreign-type spec)))
     209            (if (typep argtype 'foreign-record-type)
     210              (let* ((type0 (darwin32::record-type-has-single-scalar-field argtype)))
     211                (if type0
     212                  (progn
     213                    (rlets (list name (foreign-record-type-name argtype)))
     214                    (inits `(setf ,(%foreign-access-form name rtype 0 (foreign-record-field-name (car (foreign-record-type-fields argtype))))
     215                             (next-scalar-arg type0))))
     216                  (lets (list name (next-scalar-arg argtype)))))
     217              (lets (list name (next-scalar-arg argtype))))
     218            (when (or (typep argtype 'foreign-pointer-type)
     219                      (typep argtype 'foreign-array-type))
     220              (dynamic-extent-names name))
     221            (when use-fp-args (set-fp-regs-form)))))))))
     222
     223(defun darwin32::generate-callback-return-value (stack-ptr fp-args-ptr result return-type struct-return-arg)
     224  (unless (eq return-type *void-foreign-type*)
     225    (when (typep return-type 'foreign-record-type)
     226      ;;; Would have been mapped to :VOID unless record-type contained
     227      ;;; a single scalar field.
     228      (let* ((field0 (car (foreign-record-type-fields return-type))))
     229        (setq result (%foreign-access-form struct-return-arg
     230                                           return-type
     231                                           0
     232                                           (foreign-record-field-name field0))
     233              return-type (foreign-record-field-type field0))))
     234    (let* ((return-type-keyword (foreign-type-to-representation-type return-type))
     235           (result-ptr (case return-type-keyword
     236                   ((:single-float :double-float)
     237                    fp-args-ptr)
     238                   (t stack-ptr))))
     239      `(setf (,
     240              (case return-type-keyword
     241                                 (:address '%get-ptr)
     242                                 (:signed-doubleword '%%get-signed-longlong)
     243                                 (:unsigned-doubleword '%%get-unsigned-longlong)
     244                                 ((:double-float :single-float)
     245                                  (setq stack-ptr `(%get-ptr ,stack-ptr ,(- ppc64::c-frame.unused-1 ppc64::c-frame.param0)))
     246                                  '%get-double-float)
     247                                 (:unsigned-fullword '^get-unsigned-long)
     248                                 (t '%get-long )
     249                                 ) ,result-ptr 0) ,result))))
Note: See TracChangeset for help on using the changeset viewer.