Changeset 5754


Ignore:
Timestamp:
Jan 20, 2007, 8:55:20 PM (18 years ago)
Author:
Gary Byers
Message:

Pretty simple. 3 down, 4 to go.

File:
1 edited

Legend:

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

    r5737 r5754  
    1515;;;   http://opensource.franz.com/preamble.html
    1616
     17(in-package "CCL")
     18
     19;;; LinuxPPC32:
     20;;; Structures are never actually passed by value; the caller
     21;;; instead passes a pointer to the structure or a copy of it.
     22;;; Structures whose size is 8 bytes or less are returned in r3/r4;
     23;;; this happens rarely enough that we can probably get away with
     24;;; boxing an :UNSIGNED-DOUBLEWORD and storing it in the structure-return
     25;;; argument.
     26
     27(defun linux32::record-type-returns-structure-as-first-arg (rtype)
     28  (when (and rtype
     29             (not (typep rtype 'unsigned-byte))
     30             (not (member rtype *foreign-representation-type-keywords*
     31                          :test #'eq)))
     32    (let* ((ftype (if (typep rtype 'foreign-type)
     33                    rtype
     34                    (parse-foreign-type rtype))))
     35      (and (typep ftype 'foreign-record-type)
     36           (> (ensure-foreign-type-bits ftype) 64)))))
     37
     38
     39(defun linux32::expand-ff-call (callform args)
     40  (let* ((result-type-spec (or (car (last args)) :void))
     41         (enclosing-form nil)
     42         (result-form nil))
     43    (multiple-value-bind (result-type error)
     44        (parse-foreign-type result-type-spec)
     45      (if error
     46        (setq result-type-spec :void result-type *void-foreign-type*)
     47        (setq args (butlast args)))
     48      (collect ((argforms))
     49        (when (eq (car args) :monitor-exception-ports)
     50          (argforms (pop args)))
     51        (when (typep result-type 'foreign-record-type)
     52          (if (linux32::record-type-returns-structure-as-first-arg result-type)
     53            (progn
     54              (setq result-type *void-foreign-type*
     55                    result-type-spec :void)
     56              (argforms :address)
     57              (argforms result-form))
     58            (progn
     59              (setq result-type (parse-foreign-type :unsigned-doubleword)
     60                    result-type-spec :unsigned-doubleword
     61                    enclosing-form `(setf (%%get-unsigned-longlong ,result-form))))))
     62        (unless (evenp (length args))
     63          (error "~s should be an even-length list of alternating foreign types and values" args))       
     64                (do* ((args args (cddr args)))
     65             ((null args))
     66          (let* ((arg-type-spec (car args))
     67                 (arg-value-form (cadr args)))
     68            (if (or (member arg-type-spec *foreign-representation-type-keywords*
     69                           :test #'eq)
     70                    (typep arg-type-spec 'unsigned-byte))
     71              (progn
     72                (argforms arg-type-spec)
     73                (argforms arg-value-form))
     74              (let* ((ftype (parse-foreign-type arg-type-spec)))
     75                (if (typep ftype 'foreign-record-type)
     76                  (progn
     77                    (argforms :address)
     78                    (argforms arg-value-form))
     79                  (progn
     80                    (argforms (foreign-type-to-representation-type ftype))
     81                    (argforms arg-value-form)))))))
     82        (argforms (foreign-type-to-representation-type result-type))
     83        (let* ((call `(,@callform ,@(argforms))))
     84          (if enclosing-form
     85            `(,@enclosing-form ,call)
     86            call))))))
Note: See TracChangeset for help on using the changeset viewer.