Custom Query (1030 matches)

Filters
 
Or
 
  
 
Columns

Show under each result:


Results (265 - 267 of 1030)

Ticket Resolution Summary Owner Reporter
#342 fixed ffi-parser limitations need workaround Gary Byers Gary Byers
Description

On Fedora 9/PPC, /usr/include/asm/ioctl.h contains:

/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
	((sizeof(t) == sizeof(t[1]) && \
	  sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
	  sizeof(t) : __invalid_size_argument_for_IOC)

/* used to create numbers */
#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))

and some ioctl constants are then defined in terms of _IOR(), _IOW(), etc.

The conditional expression in the expansion of _IOC_TYPECHECK (and possibly the reference to the variable) cause the FFI parser to give up, so some IOCTL constants aren't defined.

We can either try to be more ambitious and interpret the expansion (it should always expand to "sizeof(t)" unless there's an error in the header file) or do all macroexpansion as if:

#define _IOC_TYPECHECK(t) sizeof(t)

was predefined and not overridden by the definition in the header file.

(We might be able to translate this particular macro into something that we can make sense of, but we can't always do that, so it seems like a mechanism for dealing with intractable nonsense would be desirable.)

#361 fixed Loading WebKit example fails Gary Byers Gary Byers
Description

Just trying to load the webkit framework via:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (objc:load-framework "WebKit" :webkit))

fails with an error from something in the bridge that seems not to know that method signatures of different lengths aren't EQUAL and that it should stop CDRing:

? 
> Error: Unknown foreign type: NIL
> While executing: %PARSE-FOREIGN-TYPE, in process Listener(3).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 > :b
 (13536820) : 0 (%PARSE-FOREIGN-TYPE NIL #S(FOREIGN-TYPE-DATA :TRANSLATORS #<HASH-TABLE :TEST EQ size 17/60 #x300040B2F80D> :KIND-INFO #<HASH-TABLE :TEST EQ size 164/203 #x300040B2F21D> ...)) 733
 (13536868) : 1 (PARSE-FOREIGN-TYPE NIL #S(FOREIGN-TYPE-DATA :TRANSLATORS #<HASH-TABLE :TEST EQ size 17/60 #x300040B2F80D> :KIND-INFO #<HASH-TABLE :TEST EQ size 164/203 #x300040B2F21D> ...)) 253
 (135368B0) : 2 (FUNCALL #'#<(:INTERNAL SIGNATURES-EQUAL POSTPROCESS-OBJC-MESSAGE-INFO)> (:VOID :ID) (:VOID)) 157
 (135368F8) : 3 (MEMBER-TEST (:VOID :ID) ((:<BOOL>) (:VOID)) #<Compiled-function (:INTERNAL SIGNATURES-EQUAL POSTPROCESS-OBJC-MESSAGE-INFO) (Non-Global)  #x300040EC781F>) 573
 (13536930) : 4 (ADJOIN (:VOID :ID) ((:<BOOL>) (:VOID)) :TEST #<Compiled-function (:INTERNAL SIGNATURES-EQUAL POSTPROCESS-OBJC-MESSAGE-INFO) (Non-Global)  #x300040EC781F> :TEST-NOT NIL :KEY NIL) 501
 (135369B8) : 5 (POSTPROCESS-OBJC-MESSAGE-INFO #S(OBJC-MESSAGE-INFO :MESSAGE-NAME "goForward" :METHODS (#<# -[# #] #x3000422BC61D> #<# -[# #] #x3000422BC6CD> #<# -[# #] #x300041EB79CD>) ...)) 797
#366 fixed darwinx8632 FFI issues: small structure return. R. Matthew Emerson Gary Byers
Description

(None of this is unexpected; I'm just trying to document things as I find them so that we hopefully know what to to fix.)

http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/IA32.html is nominally the authoritative ABI reference, but "whatever GCC does" is probably more authoritative ...

The reference claims that "structures whose aligned size is one or two bytes are returned in %eax, and those whose size is 4 or 8 bytes are returned in %eax and %edx". Structures of other sizes are returned via an invisible first argument.

This is pretty obviously bogus: 4-byte structures are (as one would expect) returned in %eax; %edx is undefined on return. The gcc implementers seem to be as confused by this as anyone else would be: a function that returns a 3-byte structure:

struct foo {
  short x;
  char y;
};

struct foo
getfoo()
{
  struct foo f;
  f.x = 17;
  f.y = 0;
  return f;
}

generates the following code (when compiled with -O2):

	.text
	.align 4,0x90
.globl _getfoo
_getfoo:
	pushl	%ebp
	andl	$-16711681, %eax
	movl	%esp, %ebp
	movw	$17, %ax
	leave
	ret

Ahem. Let's ignore small structures whose size isn't 1,2,4, or 8, and hope that neither CCL nor GCC ever encounter them ...

Different platforms have (wildly) different structure return conventions; AFAIK, they all support the "pointer to structure as first argument" convention in at least some cases. CCL's FFI tries to hide the differences/exceptions in different ABIs by making "high-level" foreign function calls (EXTERNAL-CALL, FF-CALL) follow the pointer-to-structure-as-first arg convention and expand into a lower-level %FF-CALL that either follows that convention or accepts the structure return value in register(s) and stores those registers into the structure in the first arg.

For instance, the x8664 ABI has a fairly bizarre convention where small structures are returned in some combination of %rax, %rdx, %xmm0, and %xmm1, according to nearly incomprehensible rules about whether the structures's halves are or are not entirely of some floating-point type.

Given:

(def-foreign-type :example
    (:struct :example
             (:x :float)
             (:y :float)))

a call to a function "foo" that returns an :example struct and assigns it to P:

  (external-call "foo" p :example)

macroexpands into:

(LET* ((#:RESULT (%NULL-PTR)))
  (DECLARE (DYNAMIC-EXTENT #:RESULT) (TYPE MACPTR #:RESULT))
  (%SETF-MACPTR #:RESULT P)
  (%STACK-BLOCK ((#:REGISTERS (+ (* 2 8) (* 2 8))))
                (%FF-CALL (%REFERENCE-EXTERNAL-ENTRY-POINT
                            (LOAD-TIME-VALUE (EXTERNAL "foo")))
                          :REGISTERS
                          #:REGISTERS
                          :VOID)
                (PROGN (SETF (%GET-UNSIGNED-LONG #:RESULT 0)
                             (%GET-UNSIGNED-LONG #:REGISTERS 16))
                       (SETF (%GET-UNSIGNED-LONG #:RESULT 4)
                             (%GET-UNSIGNED-LONG #:REGISTERS 20)))))

and there's special runtime and compiler support for obtaining all of the register results in this case. (Some other platforms return structure results in multiple registers, so the notion of a platform-dependent multiple-register return buffer is generalized in the FFI, perhaps a bit too much.) The temporary #:RESULT pointer is only there to ensure left-to-right evaluation order.

Given the same definition of the :example structure, the Darwin X8632 port compiles the same call into:

(%FF-CALL (%REFERENCE-EXTERNAL-ENTRY-POINT (LOAD-TIME-VALUE (EXTERNAL "foo"))) :ADDRESS P :VOID)

We maybe don't need the generality of returning multiple registers, since we're either going to get a single 32-bit value in %eax or a 64-bit value in %eax:%edx, so I think that this should expand into something like:

(LET* ((#:RESULT (%NULL-PTR)))
  (DECLARE (DYNAMIC-EXTENT #:RESULT) (TYPE MACPTR #:RESULT))
  (%SETF-MACPTR #:RESULT P)
  (SETF 
    (%%GET-SIGNED-LONGLONG #:RESULT 0)
    (%FF-CALL (%REFERENCE-EXTERNAL-ENTRY-POINT (LOAD-TIME-VALUE (EXTERNAL "foo")))
              :SIGNED-DOUBLEWORD)))

(assuming that I've indented and counted parens sanely and assuming that I'm thinking about endianness correctly.)

I've cut-and-pasted code from ffi-darwinx8632.lisp into the Linux and Windows x8632 files; I think that those other platforms always use the "pass as first arg" convention, so AFAIK it's just Darwin that needs to worry about this, so we should probably make sure that the other platforms just return T from the hook function that says whether or not to use that convention on those other platforms.

Batch Modify
Note: See TracBatchModify for help on using batch modify.
Note: See TracQuery for help on using queries.