Index: libffi/doc/libffi.texi =================================================================== --- libffi.orig/doc/libffi.texi +++ libffi/doc/libffi.texi @@ -171,7 +171,9 @@ discarded. @var{avalues} is a vector of @code{void *} pointers that point to the memory locations holding the argument values for a call. If @var{cif} declares that the function has no arguments (i.e., @var{nargs} was 0), -then @var{avalues} is ignored. +then @var{avalues} is ignored. Note that argument values may be +modified by the callee (for instance, structs passed by value); the +burden of copying pass-by-value arguments is placed on the caller. @end defun Index: libffi/src/x86/ffi.c =================================================================== --- libffi.orig/src/x86/ffi.c +++ libffi/src/x86/ffi.c @@ -291,27 +291,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(v { #ifdef X86_WIN64 case FFI_WIN64: - { - /* Make copies of all struct arguments - NOTE: not sure if responsibility should be here or in caller */ - unsigned int i; - for (i=0; i < cif->nargs;i++) { - size_t size = cif->arg_types[i]->size; - if ((cif->arg_types[i]->type == FFI_TYPE_STRUCT - && (size != 1 && size != 2 && size != 4 && size != 8)) -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - || cif->arg_types[i]->type == FFI_TYPE_LONGDOUBLE -#endif - ) - { - void *local = alloca(size); - memcpy(local, avalue[i], size); - avalue[i] = local; - } - } - ffi_call_win64(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - } + ffi_call_win64(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); break; #elif defined(X86_WIN32) case FFI_SYSV: Index: libffi/ChangeLog =================================================================== --- libffi.orig/ChangeLog +++ libffi/ChangeLog @@ -102,6 +102,14 @@ * fficonfig.h.in: Regenerate. * src/x86/sysv.S (.eh_frame): Use .ascii, .string or error. +2010-05-11 Dan Witte + + * doc/libffi.tex: Document previous change. + +2010-05-11 Makoto Kato + + * src/x86/ffi.c (ffi_call): Don't copy structs passed by value. + 2010-05-05 Michael Kohler * src/dlmalloc.c (dlfree): Fix spelling. Index: libffi/doc/libffi.info =================================================================== --- libffi.orig/doc/libffi.info +++ libffi/doc/libffi.info @@ -1,10 +1,10 @@ -This is doc/libffi.info, produced by makeinfo version 4.12 from -./doc/libffi.texi. +This is ../libffi/doc/libffi.info, produced by makeinfo version 4.13 +from ../libffi/doc/libffi.texi. This manual is for Libffi, a portable foreign-function interface library. - Copyright (C) 2008 Red Hat, Inc. + Copyright (C) 2008, 2010 Red Hat, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as @@ -13,7 +13,7 @@ library. included in the section entitled "GNU General Public License". -INFO-DIR-SECTION +INFO-DIR-SECTION Development START-INFO-DIR-ENTRY * libffi: (libffi). Portable foreign-function interface library. END-INFO-DIR-ENTRY @@ -27,7 +27,7 @@ libffi This manual is for Libffi, a portable foreign-function interface library. - Copyright (C) 2008 Red Hat, Inc. + Copyright (C) 2008, 2010 Red Hat, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as @@ -89,6 +89,7 @@ File: libffi.info, Node: Using libffi, * Types:: libffi type descriptions. * Multiple ABIs:: Different passing styles on one platform. * The Closure API:: Writing a generic function. +* Closure Example:: A closure example.  File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi @@ -146,7 +147,9 @@ To prepare a call interface object, use AVALUES is a vector of `void *' pointers that point to the memory locations holding the argument values for a call. If CIF declares that the function has no arguments (i.e., NARGS was 0), then - AVALUES is ignored. + AVALUES is ignored. Note that argument values may be modified by + the callee (for instance, structs passed by value); the burden of + copying pass-by-value arguments is placed on the caller.  File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: Using libffi @@ -368,7 +371,7 @@ instance, the x86 platform has both `std necessarily platform-specific.  -File: libffi.info, Node: The Closure API, Prev: Multiple ABIs, Up: Using libffi +File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multiple ABIs, Up: Using libffi 2.5 The Closure API =================== @@ -444,6 +447,62 @@ is deprecated, as it cannot handle the n executable addresses.  +File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using libffi + +2.6 Closure Example +=================== + +A trivial example that creates a new `puts' by binding `fputs' with +`stdin'. + + #include + #include + + /* Acts like puts with the file given at time of enclosure. */ + void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], + FILE *stream) + { + *ret = fputs(*(char **)args[0], stream); + } + + int main() + { + ffi_cif cif; + ffi_type *args[1]; + ffi_closure *closure; + + int (*bound_puts)(char *); + int rc; + + /* Allocate closure and bound_puts */ + closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); + + if (closure) + { + /* Initialize the argument info vectors */ + args[0] = &ffi_type_pointer; + + /* Initialize the cif */ + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uint, args) == FFI_OK) + { + /* Initialize the closure, setting stream to stdout */ + if (ffi_prep_closure_loc(closure, &cif, puts_binding, + stdout, bound_puts) == FFI_OK) + { + rc = bound_puts("Hello World!"); + /* rc now holds the result of the call to fputs */ + } + } + } + + /* Deallocate both closure, and bound_puts */ + ffi_closure_free(closure); + + return 0; + } + + File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top 3 Missing Features @@ -480,7 +539,7 @@ Index * closures: The Closure API. (line 13) * FFI: Introduction. (line 31) * ffi_call: The Basics. (line 41) -* ffi_closure_alloca: The Closure API. (line 19) +* ffi_closure_alloc: The Closure API. (line 19) * ffi_closure_free: The Closure API. (line 26) * FFI_CLOSURES: The Closure API. (line 13) * ffi_prep_cif: The Basics. (line 16) @@ -516,18 +575,19 @@ Index  Tag Table: -Node: Top670 -Node: Introduction1406 -Node: Using libffi3042 -Node: The Basics3477 -Node: Simple Example6084 -Node: Types7111 -Node: Primitive Types7394 -Node: Structures9214 -Node: Type Example10074 -Node: Multiple ABIs11297 -Node: The Closure API11668 -Node: Missing Features14588 -Node: Index15081 +Node: Top706 +Node: Introduction1448 +Node: Using libffi3084 +Node: The Basics3570 +Node: Simple Example6356 +Node: Types7383 +Node: Primitive Types7666 +Node: Structures9486 +Node: Type Example10346 +Node: Multiple ABIs11569 +Node: The Closure API11940 +Node: Closure Example14884 +Node: Missing Features16443 +Node: Index16936  End Tag Table