From 63af3522ffbd5c3e1003a908d804c4e079d8f5e8 Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Fri, 15 Feb 2008 10:06:35 +0100 Subject: LOW-LEVEL-INVOKE: Support structs and unions as return values. darcs-hash:a9f8de5297e856e6c7f05ccb34a8506d47ef9175 --- Lisp/method-invocation.lisp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'Lisp/method-invocation.lisp') diff --git a/Lisp/method-invocation.lisp b/Lisp/method-invocation.lisp index c90b37d..85b8b0d 100644 --- a/Lisp/method-invocation.lisp +++ b/Lisp/method-invocation.lisp @@ -332,8 +332,11 @@ easier to use with __apply__. (- argc 2)) (objc-arg-ptrs :pointer argc) (objc-return-value-cell - ;; FIXME: This won't work for - ;; structs, arrays and unions! + ;; Note that this cell is not used + ;; if the method returns a struct, + ;; array or union. For these, see + ;; OBJC-STRUCT-RETURN-VALUE-CELL + ;; below. (if (eq return-c-type :void) :int return-c-type)) @@ -423,12 +426,22 @@ easier to use with __apply__. ((nil) 0) ((t) 1) (otherwise arg))))))) - (let* ((error-cell + (let* ((objc-struct-return-value-cell + (if (member (typespec-primary-type return-type) + '(struct union array)) + ;; Note that sizeof(char) is defined to be 1. That + ;; is, sizeof returns a size in units of chars, not + ;; in units of bytes. + (foreign-alloc :char :count (%objcl-sizeof-type + return-typestring)) + nil)) + (error-cell (%objcl-invoke-with-types (- argc 2) superclass-pointer-for-send-super return-typestring objc-arg-typestrings - objc-return-value-cell + (or objc-struct-return-value-cell + objc-return-value-cell) objc-arg-ptrs))) (unless (cffi:null-pointer-p error-cell) (error (make-condition 'exception :pointer error-cell))) @@ -448,6 +461,10 @@ easier to use with __apply__. return-c-type) receiver selector)) + ((struct union array) + ;; The caller is responsible for FOREIGN-FREEing the + ;; return value. + objc-struct-return-value-cell) ((:void) (values)) (otherwise (cffi:mem-ref objc-return-value-cell return-c-type))))))))) -- cgit v1.2.3