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  <dwitte@mozilla.com>
+
+	* doc/libffi.tex: Document previous change.
+
+2010-05-11  Makoto Kato <m_kato@ga2.so-net.ne.jp>
+
+	* src/x86/ffi.c (ffi_call): Don't copy structs passed by value.
+
 2010-05-05  Michael Kohler <michaelkohler@live.com>
 
 	* 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 <stdio.h>
+     #include <ffi.h>
+
+     /* 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
