Index: Modules/_ctypes/libffi/ChangeLog.libffi =================================================================== --- Modules/_ctypes/libffi/ChangeLog.libffi (revision 79097) +++ Modules/_ctypes/libffi/ChangeLog.libffi (working copy) @@ -1,87 +1,42 @@ -2009-12-27 Matthias Klose +2010-01-15 Anthony Green - * configure.ac (HAVE_LONG_DOUBLE): Define for mips when - appropriate. - * configure: Rebuilt. + * README: Add notes on building with Microsoft Visual C++. -2009-12-27 Anthony Green +2010-01-15 Daniel Witte - * testsuite/libffi.call/cls_longdouble.c: Don't xfail for ARM. + * msvcc.sh: New file. -2009-12-26 Anthony Green + * src/x86/win32.S: Port assembly routines to MSVC and #ifdef. + * src/x86/ffi.c: Tweak function declaration and remove excess + parens. + * include/ffi.h.in: Add __declspec(align(8)) to typedef struct + ffi_closure. - * testsuite/libffi.call/huge_struct.c: Don't xfail for avr32*-*-*. - * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for - avr32*-*-*. - * testsuite/libffi.call/cls_double_va.c: Ditto. + * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new + function ffi_call_win32 on X86_WIN32. + * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32. + (ffi_call_STDCALL): Remove. -2009-12-26 Andreas Tobler + * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code + to ffi_prep_cif_machdep for x86. + * src/x86/ffi.c (ffi_prep_cif_machdep): To here. - * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h - and inttypes.h. - * testsuite/libffi.special/unwindtest.cc: Ditto. - * testsuite/libffi.call/huge_struct.c: Don't include stdint.h - directly. +2010-01-15 Oliver Kiddle -2009-12-26 Andreas Tobler + * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for + Sun Studio compiler compatibility. - * configure.ac: Add amd64-*-openbsd*. - * configure: Rebuilt. - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link - openbsd programs with -lpthread. +2010-01-12 Conrad Irwin -2009-12-26 Anthony Green + * doc/libffi.texi: Add closure example. + * doc/libffi.info: Rebuilt. - * testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for - mips*-*-* and arm*-*-*. - * testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c, - testsuite/libffi.call/stret_medium2.c, - testsuite/libffi.call/stret_medium.c, - testsuite/libffi.call/stret_large.c, - testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. - -2009-12-26 Andreas Tobler - Anthony Green - - * testsuite/libffi.call/huge_struct.c (test_large_fn): Replace - format code %p with %#lx because %p does not add a leading 0x on - Solaris. Also change relevant arguments to unsigned long. - 2009-12-25 Samuli Suominen * configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64. * configure: Rebuilt. * fficonfig.h.in: Rebuilt. -2009-12-29 Kay Tietz - - * testsuite/libffi.call/ffitest.h, - testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix - definitions. - -2009-12-25 Carlo Bramini - - * configure.ac (AM_LTLDFLAGS): Define for windows hosts. - * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. - * configure: Rebuilt. - * Makefile.in: Rebuilt. - -2009-12-24 Anthony Green - - * testsuite/libffi.call/huge_struct.c: Fix printf format, and - don't xfail x86 Linux. - * testsuite/libffi.call/huge_struct.c: Don't xfail mips. - * testsuite/libffi.call/cls_pointer.c: Ditto. - * testsuite/libffi.call/cls_pointer_stack.c: Ditto. - * testsuite/libffi.call/cls_longdouble_va.c: Ditto. - * testsuite/libffi.call/cls_longdouble.c: Ditto. - * testsuite/libffi.call/cls_double_va.c: Ditto. - 2009-06-16 Andrew Haley * testsuite/libffi.call/cls_align_sint64.c, @@ -257,20 +212,20 @@ 2008-12-22 Timothy Wall * testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/closure_loc_fn0.c, - testsuite/libffi.call/closure_stdcall.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_loc_fn0.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_pointer.c, testsuite/libffi.call/cls_pointer_stack.c: use portable cast from pointer to integer (intptr_t). * testsuite/libffi.call/cls_longdouble.c: disable for win64. - + 2008-12-19 Anthony Green * configure.ac: Bump version to 3.0.8. Index: Modules/_ctypes/libffi/configure =================================================================== --- Modules/_ctypes/libffi/configure (revision 79098) +++ Modules/_ctypes/libffi/configure (working copy) @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for libffi 3.0.9. +# Generated by GNU Autoconf 2.65 for libffi 3.0.10rc0. # # Report bugs to . # @@ -701,8 +701,8 @@ # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='3.0.9' -PACKAGE_STRING='libffi 3.0.9' +PACKAGE_VERSION='3.0.10rc0' +PACKAGE_STRING='libffi 3.0.10rc0' PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html' PACKAGE_URL='' @@ -1489,7 +1489,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 3.0.9 to adapt to many kinds of systems. +\`configure' configures libffi 3.0.10rc0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1560,7 +1560,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 3.0.9:";; + short | recursive ) echo "Configuration of libffi 3.0.10rc0:";; esac cat <<\_ACEOF @@ -1667,7 +1667,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 3.0.9 +libffi configure 3.0.10rc0 generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. @@ -2216,7 +2216,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 3.0.9, which was +It was created by libffi $as_me 3.0.10rc0, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -3142,7 +3142,7 @@ # Define the identity of the package. PACKAGE='libffi' - VERSION='3.0.9' + VERSION='3.0.10rc0' cat >>confdefs.h <<_ACEOF @@ -11192,6 +11192,10 @@ TARGET=X86_64; TARGETDIR=x86 ;; + amd64-*-freebsd*) + TARGET=X86_64; TARGETDIR=x86 + ;; + avr32*-*-*) TARGET=AVR32; TARGETDIR=avr32 ;; @@ -13069,7 +13073,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 3.0.9, which was +This file was extended by libffi $as_me 3.0.10rc0, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13139,7 +13143,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libffi config.status 3.0.9 +libffi config.status 3.0.10rc0 configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" Index: Modules/_ctypes/libffi/msvcc.sh =================================================================== --- Modules/_ctypes/libffi/msvcc.sh (revision 0) +++ Modules/_ctypes/libffi/msvcc.sh (revision 0) @@ -0,0 +1,185 @@ +#!/bin/sh + +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the MSVC wrappificator. +# +# The Initial Developer of the Original Code is +# Timothy Wall . +# Portions created by the Initial Developer are Copyright (C) 2009 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Daniel Witte +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +# +# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC +# format and translated into something sensible for cl or ml. +# + +# Disable specific warnings, and enable warnings-as-errors so we catch any +# mistranslated args. +nowarn="-wd4127 -wd4820 -wd4706 -wd4100 -wd4255 -wd4668 -wd4053 -wd4324" +args="-nologo -W3 -WX $nowarn" +md=-MD +cl="cl" +ml="ml" +output= + +while [ $# -gt 0 ] +do + case $1 + in + -fexceptions) + # Don't enable exceptions for now. + #args="$args -EHac" + shift 1 + ;; + -m32) + shift 1 + ;; + -m64) + cl="cl" # "$MSVC/x86_amd64/cl" + ml="ml64" # "$MSVC/x86_amd64/ml64" + shift 1 + ;; + -O*) + args="$args $1" + shift 1 + ;; + -g) + # Can't specify -RTC1 or -Zi in opt. -Gy is ok. Use -OPT:REF? + args="$args -D_DEBUG -RTC1 -Zi" + md=-MDd + shift 1 + ;; + -c) + args="$args -c" + args="$(echo $args | sed 's%/Fe%/Fo%g')" + single="-c" + shift 1 + ;; + -D*=*) + name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')" + value="$(echo $1|sed 's/-D[^=][^=]*=//g')" + args="$args -D${name}='$value'" + defines="$defines -D${name}='$value'" + shift 1 + ;; + -D*) + args="$args $1" + defines="$defines $1" + shift 1 + ;; + -I) + args="$args -I$2" + includes="$includes -I$2" + shift 2 + ;; + -I*) + args="$args $1" + includes="$includes $1" + shift 1 + ;; + -W|-Wextra) + # TODO map extra warnings + shift 1 + ;; + -Wall) + args="$args -Wall" + shift 1 + ;; + -Werror) + args="$args -WX" + shift 1 + ;; + -W*) + # TODO map specific warnings + shift 1 + ;; + -S) + args="$args -FAs" + shift 1 + ;; + -o) + outdir="$(dirname $2)" + base="$(basename $2|sed 's/\.[^.]*//g')" + if [ -n "$single" ]; then + output="-Fo$2" + else + output="-Fe$2" + fi + if [ -n "$assembly" ]; then + args="$args $output" + else + args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base" + fi + shift 2 + ;; + *.S) + src=$1 + assembly="true" + shift 1 + ;; + *.c) + args="$args $1" + shift 1 + ;; + *) + # Assume it's an MSVC argument, and pass it through. + args="$args $1" + shift 1 + ;; + esac +done + +if [ -n "$assembly" ]; then + if [ -z "$outdir" ]; then + outdir="." + fi + ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')" + echo "$cl -nologo -EP $includes $defines $src > $ppsrc" + "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $? + output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')" + args="-nologo -safeseh $single $output $ppsrc" + + echo "$ml $args" + eval "\"$ml\" $args" + result=$? + + # required to fix ml64 broken output? + #mv *.obj $outdir +else + args="$md $args" + echo "$cl $args" + eval "\"$cl\" $args" + result=$? +fi + +exit $result + Index: Modules/_ctypes/libffi/fficonfig.h.in =================================================================== --- Modules/_ctypes/libffi/fficonfig.h.in (revision 79097) +++ Modules/_ctypes/libffi/fficonfig.h.in (working copy) @@ -125,6 +125,9 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME +/* Define to the home page for this package. */ +#undef PACKAGE_URL + /* Define to the version of this package. */ #undef PACKAGE_VERSION Index: Modules/_ctypes/libffi/src/closures.c =================================================================== --- Modules/_ctypes/libffi/src/closures.c (revision 79097) +++ Modules/_ctypes/libffi/src/closures.c (working copy) @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - closures.c - Copyright (c) 2007, 2009 Red Hat, Inc. + closures.c - Copyright (c) 2007 Red Hat, Inc. Copyright (C) 2007, 2009 Free Software Foundation, Inc Code to allocate and deallocate memory for closures. @@ -209,8 +209,6 @@ #if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) -#if FFI_MMAP_EXEC_SELINUX - /* A mutex used to synchronize access to *exec* variables in this file. */ static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -480,27 +478,6 @@ return dlmmap_locked (start, length, prot, flags, offset); } -#else - -static void * -dlmmap (void *start, size_t length, int prot, - int flags, int fd, off_t offset) -{ - - assert (start == NULL && length % malloc_getpagesize == 0 - && prot == (PROT_READ | PROT_WRITE) - && flags == (MAP_PRIVATE | MAP_ANONYMOUS) - && fd == -1 && offset == 0); - -#if FFI_CLOSURE_TEST - printf ("mapping in %zi\n", length); -#endif - - return mmap (start, length, prot | PROT_EXEC, flags, fd, offset); -} - -#endif - /* Release memory at the given address, as well as the corresponding executable page if it's separate. */ static int Index: Modules/_ctypes/libffi/src/moxie/ffitarget.h =================================================================== --- Modules/_ctypes/libffi/src/moxie/ffitarget.h (revision 0) +++ Modules/_ctypes/libffi/src/moxie/ffitarget.h (revision 0) @@ -0,0 +1,56 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2009 Anthony Green + Target configuration macros for Moxie + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + +#ifdef MOXIE + FFI_EABI, + FFI_DEFAULT_ABI = FFI_EABI, +#endif + + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 0 +#define FFI_NATIVE_RAW_API 0 + +/* Trampolines are 5 4-byte instructions long. */ +#define FFI_TRAMPOLINE_SIZE (5*4) + +#endif Index: Modules/_ctypes/libffi/src/moxie/eabi.S =================================================================== --- Modules/_ctypes/libffi/src/moxie/eabi.S (revision 0) +++ Modules/_ctypes/libffi/src/moxie/eabi.S (revision 0) @@ -0,0 +1,128 @@ +/* ----------------------------------------------------------------------- + eabi.S - Copyright (c) 2004 Anthony Green + + FR-V Assembly glue. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include +#include + + .globl ffi_prep_args_EABI + + .text + .p2align 4 + .globl ffi_call_EABI + .type ffi_call_EABI, @function + + # gr8 : ffi_prep_args + # gr9 : &ecif + # gr10: cif->bytes + # gr11: fig->flags + # gr12: ecif.rvalue + # gr13: fn + +ffi_call_EABI: + addi sp, #-80, sp + sti fp, @(sp, #24) + addi sp, #24, fp + movsg lr, gr5 + + /* Make room for the new arguments. */ + /* subi sp, fp, gr10 */ + + /* Store return address and incoming args on stack. */ + sti gr5, @(fp, #8) + sti gr8, @(fp, #-4) + sti gr9, @(fp, #-8) + sti gr10, @(fp, #-12) + sti gr11, @(fp, #-16) + sti gr12, @(fp, #-20) + sti gr13, @(fp, #-24) + + sub sp, gr10, sp + + /* Call ffi_prep_args. */ + ldi @(fp, #-4), gr4 + addi sp, #0, gr8 + ldi @(fp, #-8), gr9 +#ifdef __FRV_FDPIC__ + ldd @(gr4, gr0), gr14 + calll @(gr14, gr0) +#else + calll @(gr4, gr0) +#endif + + /* ffi_prep_args returns the new stack pointer. */ + mov gr8, gr4 + + ldi @(sp, #0), gr8 + ldi @(sp, #4), gr9 + ldi @(sp, #8), gr10 + ldi @(sp, #12), gr11 + ldi @(sp, #16), gr12 + ldi @(sp, #20), gr13 + + /* Always copy the return value pointer into the hidden + parameter register. This is only strictly necessary + when we're returning an aggregate type, but it doesn't + hurt to do this all the time, and it saves a branch. */ + ldi @(fp, #-20), gr3 + + /* Use the ffi_prep_args return value for the new sp. */ + mov gr4, sp + + /* Call the target function. */ + ldi @(fp, -24), gr4 +#ifdef __FRV_FDPIC__ + ldd @(gr4, gr0), gr14 + calll @(gr14, gr0) +#else + calll @(gr4, gr0) +#endif + + /* Store the result. */ + ldi @(fp, #-16), gr10 /* fig->flags */ + ldi @(fp, #-20), gr4 /* ecif.rvalue */ + + /* Is the return value stored in two registers? */ + cmpi gr10, #8, icc0 + bne icc0, 0, .L2 + /* Yes, save them. */ + sti gr8, @(gr4, #0) + sti gr9, @(gr4, #4) + bra .L3 +.L2: + /* Is the return value a structure? */ + cmpi gr10, #-1, icc0 + beq icc0, 0, .L3 + /* No, save a 4 byte return value. */ + sti gr8, @(gr4, #0) +.L3: + + /* Restore the stack, and return. */ + ldi @(fp, 8), gr5 + ld @(fp, gr0), fp + addi sp,#80,sp + jmpl @(gr5,gr0) + .size ffi_call_EABI, .-ffi_call_EABI + Index: Modules/_ctypes/libffi/src/moxie/ffi.c =================================================================== --- Modules/_ctypes/libffi/src/moxie/ffi.c (revision 0) +++ Modules/_ctypes/libffi/src/moxie/ffi.c (revision 0) @@ -0,0 +1,276 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (C) 2009 Anthony Green + + Moxie Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include + +#include + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void *ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + register int count = 0; + + p_argv = ecif->avalue; + argp = stack; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + z = sizeof(void*); + *(void **) argp = *p_argv; + } + /* if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + if (count > 24) + { + // This is going on the stack. Turn it into a double. + *(double *) argp = (double) *(float*)(* p_argv); + z = sizeof(double); + } + else + *(void **) argp = *(void **)(* p_argv); + } */ + else if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof(int)) + { + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } + else + { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + count += z; + } + + return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8))); +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + if (cif->rtype->type == FFI_TYPE_STRUCT) + cif->flags = -1; + else + cif->flags = cif->rtype->size; + + cif->bytes = ALIGN (cif->bytes, 8); + + return FFI_OK; +} + +extern void ffi_call_EABI(void *(*)(char *, extended_cif *), + extended_cif *, + unsigned, unsigned, + unsigned *, + void (*fn)(void)); + +void ffi_call(ffi_cif *cif, + void (*fn)(void), + void *rvalue, + void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { + case FFI_EABI: + ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + default: + FFI_ASSERT(0); + break; + } +} + +void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, + unsigned arg4, unsigned arg5, unsigned arg6) +{ + /* This function is called by a trampoline. The trampoline stows a + pointer to the ffi_closure object in gr7. We must save this + pointer in a place that will persist while we do our work. */ + register ffi_closure *creg __asm__ ("gr7"); + ffi_closure *closure = creg; + + /* Arguments that don't fit in registers are found on the stack + at a fixed offset above the current frame pointer. */ + register char *frame_pointer __asm__ ("fp"); + char *stack_args = frame_pointer + 16; + + /* Lay the register arguments down in a continuous chunk of memory. */ + unsigned register_args[6] = + { arg1, arg2, arg3, arg4, arg5, arg6 }; + + ffi_cif *cif = closure->cif; + ffi_type **arg_types = cif->arg_types; + void **avalue = alloca (cif->nargs * sizeof(void *)); + char *ptr = (char *) register_args; + int i; + + /* Find the address of each argument. */ + for (i = 0; i < cif->nargs; i++) + { + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = ptr + 3; + break; + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = ptr + 2; + break; + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_FLOAT: + avalue[i] = ptr; + break; + case FFI_TYPE_STRUCT: + avalue[i] = *(void**)ptr; + break; + default: + /* This is an 8-byte value. */ + avalue[i] = ptr; + ptr += 4; + break; + } + ptr += 4; + + /* If we've handled more arguments than fit in registers, + start looking at the those passed on the stack. */ + if (ptr == ((char *)register_args + (6*4))) + ptr = stack_args; + } + + /* Invoke the closure. */ + if (cif->rtype->type == FFI_TYPE_STRUCT) + { + /* The caller allocates space for the return structure, and + passes a pointer to this space in gr3. Use this value directly + as the return value. */ + register void *return_struct_ptr __asm__("gr3"); + (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data); + } + else + { + /* Allocate space for the return value and call the function. */ + long long rvalue; + (closure->fun) (cif, &rvalue, avalue, closure->user_data); + + /* Functions return 4-byte or smaller results in gr8. 8-byte + values also use gr9. We fill the both, even for small return + values, just to avoid a branch. */ + asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue)); + asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1])); + } +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + unsigned long fn = (long) ffi_closure_eabi; + unsigned long cls = (long) codeloc; + int i; + + fn = (unsigned long) ffi_closure_eabi; + + tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ + tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ + tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */ + tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */ + tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */ + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + /* Cache flushing. */ + for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++) + __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i), + "r" (codeloc)); + + return FFI_OK; +} Index: Modules/_ctypes/libffi/src/x86/ffi64.c =================================================================== --- Modules/_ctypes/libffi/src/x86/ffi64.c (revision 79097) +++ Modules/_ctypes/libffi/src/x86/ffi64.c (working copy) @@ -50,9 +50,10 @@ gcc/config/i386/i386.c. Do *not* change one without the other. */ /* Register class used for passing given 64bit part of the argument. - These represent classes as documented by the PS ABI, with the exception - of SSESF, SSEDF classes, that are basically SSE class, just gcc will - use SF or DFmode move instead of DImode to avoid reformatting penalties. + These represent classes as documented by the PS ABI, with the + exception of SSESF, SSEDF classes, that are basically SSE class, + just gcc will use SF or DFmode move instead of DImode to avoid + reformatting penalties. Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves whenever possible (upper half does contain padding). */ Index: Modules/_ctypes/libffi/src/x86/ffitarget.h =================================================================== --- Modules/_ctypes/libffi/src/x86/ffitarget.h (revision 79097) +++ Modules/_ctypes/libffi/src/x86/ffitarget.h (working copy) @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + ffitarget.h - Copyright (c) 1996-2003, 2010 Red Hat, Inc. Copyright (C) 2008 Free Software Foundation, Inc. Target configuration macros for x86 and x86-64. @@ -74,10 +74,10 @@ #else /* ---- Intel x86 and AMD x86-64 - */ -#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) +#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__) || defined(__i386) || defined(__amd64)) FFI_SYSV, FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ -#ifdef __i386__ +#if defined(__i386__) || defined(__i386) FFI_DEFAULT_ABI = FFI_SYSV, #else FFI_DEFAULT_ABI = FFI_UNIX64, Index: Modules/_ctypes/libffi/src/x86/win32.S =================================================================== --- Modules/_ctypes/libffi/src/x86/win32.S (revision 79097) +++ Modules/_ctypes/libffi/src/x86/win32.S (working copy) @@ -2,6 +2,7 @@ win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009 Red Hat, Inc. Copyright (c) 2001 John Beniton Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2009 Daniel Witte X86 Foreign Function Interface @@ -31,14 +32,371 @@ #define LIBFFI_ASM #include #include - + +#ifdef _MSC_VER + +.386 +.MODEL FLAT, C + +EXTRN ffi_closure_SYSV_inner:NEAR + +_TEXT SEGMENT + +ffi_call_win32 PROC NEAR, + ffi_prep_args : NEAR PTR DWORD, + ecif : NEAR PTR DWORD, + cif_bytes : DWORD, + cif_flags : DWORD, + rvalue : NEAR PTR DWORD, + fn : NEAR PTR DWORD + + ;; Make room for all of the new args. + mov ecx, cif_bytes + sub esp, ecx + + mov eax, esp + + ;; Place all of the ffi_prep_args in position + push ecif + push eax + call ffi_prep_args + + ;; Return stack to previous state and call the function + add esp, 8 + + call fn + + ;; cdecl: we restore esp in the epilogue, so there's no need to + ;; remove the space we pushed for the args. + ;; stdcall: the callee has already cleaned the stack. + + ;; Load ecx with the return type code + mov ecx, cif_flags + + ;; If the return value pointer is NULL, assume no return value. + cmp rvalue, 0 + jne ca_jumptable + + ;; Even if there is no space for the return value, we are + ;; obliged to handle floating-point values. + cmp ecx, FFI_TYPE_FLOAT + jne ca_epilogue + fstp st(0) + + jmp ca_epilogue + +ca_jumptable: + jmp [ca_jumpdata + 4 * ecx] +ca_jumpdata: + ;; Do not insert anything here between label and jump table. + dd offset ca_epilogue ;; FFI_TYPE_VOID + dd offset ca_retint ;; FFI_TYPE_INT + dd offset ca_retfloat ;; FFI_TYPE_FLOAT + dd offset ca_retdouble ;; FFI_TYPE_DOUBLE + dd offset ca_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset ca_retint8 ;; FFI_TYPE_UINT8 + dd offset ca_retint8 ;; FFI_TYPE_SINT8 + dd offset ca_retint16 ;; FFI_TYPE_UINT16 + dd offset ca_retint16 ;; FFI_TYPE_SINT16 + dd offset ca_retint ;; FFI_TYPE_UINT32 + dd offset ca_retint ;; FFI_TYPE_SINT32 + dd offset ca_retint64 ;; FFI_TYPE_UINT64 + dd offset ca_retint64 ;; FFI_TYPE_SINT64 + dd offset ca_epilogue ;; FFI_TYPE_STRUCT + dd offset ca_retint ;; FFI_TYPE_POINTER + dd offset ca_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset ca_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset ca_retint ;; FFI_TYPE_SMALL_STRUCT_4B + +ca_retint8: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], al + jmp ca_epilogue + +ca_retint16: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], ax + jmp ca_epilogue + +ca_retint: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], eax + jmp ca_epilogue + +ca_retint64: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], eax + mov [ecx + 4], edx + jmp ca_epilogue + +ca_retfloat: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + fstp DWORD PTR [ecx] + jmp ca_epilogue + +ca_retdouble: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + fstp QWORD PTR [ecx] + jmp ca_epilogue + +ca_retlongdouble: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + fstp TBYTE PTR [ecx] + jmp ca_epilogue + +ca_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_call_win32 ENDP + +ffi_closure_SYSV PROC NEAR FORCEFRAME + ;; the ffi_closure ctx is passed in eax by the trampoline. + + sub esp, 40 + lea edx, [ebp - 24] + mov [ebp - 12], edx ;; resp + lea edx, [ebp + 8] + mov [esp + 8], edx ;; args + lea edx, [ebp - 12] + mov [esp + 4], edx ;; &resp + mov [esp], eax ;; closure + call ffi_closure_SYSV_inner + mov ecx, [ebp - 12] + +cs_jumptable: + jmp [cs_jumpdata + 4 * eax] +cs_jumpdata: + ;; Do not insert anything here between the label and jump table. + dd offset cs_epilogue ;; FFI_TYPE_VOID + dd offset cs_retint ;; FFI_TYPE_INT + dd offset cs_retfloat ;; FFI_TYPE_FLOAT + dd offset cs_retdouble ;; FFI_TYPE_DOUBLE + dd offset cs_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset cs_retint8 ;; FFI_TYPE_UINT8 + dd offset cs_retint8 ;; FFI_TYPE_SINT8 + dd offset cs_retint16 ;; FFI_TYPE_UINT16 + dd offset cs_retint16 ;; FFI_TYPE_SINT16 + dd offset cs_retint ;; FFI_TYPE_UINT32 + dd offset cs_retint ;; FFI_TYPE_SINT32 + dd offset cs_retint64 ;; FFI_TYPE_UINT64 + dd offset cs_retint64 ;; FFI_TYPE_SINT64 + dd offset cs_retstruct ;; FFI_TYPE_STRUCT + dd offset cs_retint ;; FFI_TYPE_POINTER + dd offset cs_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cs_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cs_retint ;; FFI_TYPE_SMALL_STRUCT_4B + +cs_retint8: + mov al, [ecx] + jmp cs_epilogue + +cs_retint16: + mov ax, [ecx] + jmp cs_epilogue + +cs_retint: + mov eax, [ecx] + jmp cs_epilogue + +cs_retint64: + mov eax, [ecx + 0] + mov edx, [ecx + 4] + jmp cs_epilogue + +cs_retfloat: + fld DWORD PTR [ecx] + jmp cs_epilogue + +cs_retdouble: + fld QWORD PTR [ecx] + jmp cs_epilogue + +cs_retlongdouble: + fld TBYTE PTR [ecx] + jmp cs_epilogue + +cs_retstruct: + ;; Caller expects us to pop struct return value pointer hidden arg. + ;; Epilogue code is autogenerated. + ret 4 + +cs_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_closure_SYSV ENDP + +#if !FFI_NO_RAW_API + +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3) +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) +#define CIF_FLAGS_OFFSET 20 + +ffi_closure_raw_SYSV PROC NEAR USES esi + ;; the ffi_closure ctx is passed in eax by the trampoline. + + sub esp, 40 + mov esi, [eax + RAW_CLOSURE_CIF_OFFSET] ;; closure->cif + mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data + mov [esp + 12], edx ;; user_data + lea edx, [ebp + 8] + mov [esp + 8], edx ;; raw_args + lea edx, [ebp - 24] + mov [esp + 4], edx ;; &res + mov [esp], esi ;; cif + call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET] ;; closure->fun + mov eax, [esi + CIF_FLAGS_OFFSET] ;; cif->flags + lea ecx, [ebp - 24] + +cr_jumptable: + jmp [cr_jumpdata + 4 * eax] +cr_jumpdata: + ;; Do not insert anything here between the label and jump table. + dd offset cr_epilogue ;; FFI_TYPE_VOID + dd offset cr_retint ;; FFI_TYPE_INT + dd offset cr_retfloat ;; FFI_TYPE_FLOAT + dd offset cr_retdouble ;; FFI_TYPE_DOUBLE + dd offset cr_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset cr_retint8 ;; FFI_TYPE_UINT8 + dd offset cr_retint8 ;; FFI_TYPE_SINT8 + dd offset cr_retint16 ;; FFI_TYPE_UINT16 + dd offset cr_retint16 ;; FFI_TYPE_SINT16 + dd offset cr_retint ;; FFI_TYPE_UINT32 + dd offset cr_retint ;; FFI_TYPE_SINT32 + dd offset cr_retint64 ;; FFI_TYPE_UINT64 + dd offset cr_retint64 ;; FFI_TYPE_SINT64 + dd offset cr_epilogue ;; FFI_TYPE_STRUCT + dd offset cr_retint ;; FFI_TYPE_POINTER + dd offset cr_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cr_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cr_retint ;; FFI_TYPE_SMALL_STRUCT_4B + +cr_retint8: + mov al, [ecx] + jmp cr_epilogue + +cr_retint16: + mov ax, [ecx] + jmp cr_epilogue + +cr_retint: + mov eax, [ecx] + jmp cr_epilogue + +cr_retint64: + mov eax, [ecx + 0] + mov edx, [ecx + 4] + jmp cr_epilogue + +cr_retfloat: + fld DWORD PTR [ecx] + jmp cr_epilogue + +cr_retdouble: + fld QWORD PTR [ecx] + jmp cr_epilogue + +cr_retlongdouble: + fld TBYTE PTR [ecx] + jmp cr_epilogue + +cr_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_closure_raw_SYSV ENDP + +#endif /* !FFI_NO_RAW_API */ + +ffi_closure_STDCALL PROC NEAR FORCEFRAME + ;; the ffi_closure ctx is passed in eax by the trampoline. + + sub esp, 40 + lea edx, [ebp - 24] + mov [ebp - 12], edx ;; resp + lea edx, [ebp + 12] ;; account for stub return address on stack + mov [esp + 8], edx ;; args + lea edx, [ebp - 12] + mov [esp + 4], edx ;; &resp + mov [esp], eax ;; closure + call ffi_closure_SYSV_inner + mov ecx, [ebp - 12] + +cd_jumptable: + jmp [cd_jumpdata + 4 * eax] +cd_jumpdata: + ;; Do not insert anything here between the label and jump table. + dd offset cd_epilogue ;; FFI_TYPE_VOID + dd offset cd_retint ;; FFI_TYPE_INT + dd offset cd_retfloat ;; FFI_TYPE_FLOAT + dd offset cd_retdouble ;; FFI_TYPE_DOUBLE + dd offset cd_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset cd_retint8 ;; FFI_TYPE_UINT8 + dd offset cd_retint8 ;; FFI_TYPE_SINT8 + dd offset cd_retint16 ;; FFI_TYPE_UINT16 + dd offset cd_retint16 ;; FFI_TYPE_SINT16 + dd offset cd_retint ;; FFI_TYPE_UINT32 + dd offset cd_retint ;; FFI_TYPE_SINT32 + dd offset cd_retint64 ;; FFI_TYPE_UINT64 + dd offset cd_retint64 ;; FFI_TYPE_SINT64 + dd offset cd_epilogue ;; FFI_TYPE_STRUCT + dd offset cd_retint ;; FFI_TYPE_POINTER + dd offset cd_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cd_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cd_retint ;; FFI_TYPE_SMALL_STRUCT_4B + +cd_retint8: + mov al, [ecx] + jmp cd_epilogue + +cd_retint16: + mov ax, [ecx] + jmp cd_epilogue + +cd_retint: + mov eax, [ecx] + jmp cd_epilogue + +cd_retint64: + mov eax, [ecx + 0] + mov edx, [ecx + 4] + jmp cd_epilogue + +cd_retfloat: + fld DWORD PTR [ecx] + jmp cd_epilogue + +cd_retdouble: + fld QWORD PTR [ecx] + jmp cd_epilogue + +cd_retlongdouble: + fld TBYTE PTR [ecx] + jmp cd_epilogue + +cd_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_closure_STDCALL ENDP + +_TEXT ENDS +END + +#else + .text # This assumes we are using gas. .balign 16 - .globl _ffi_call_SYSV - .def _ffi_call_SYSV; .scl 2; .type 32; .endef -_ffi_call_SYSV: + .globl _ffi_call_win32 + .def _ffi_call_win32; .scl 2; .type 32; .endef +_ffi_call_win32: .LFB1: pushl %ebp .LCFI0: @@ -61,8 +419,10 @@ # FIXME: Align the stack to a 128-bit boundary to avoid # potential performance hits. - call *28(%ebp) + call *28(%ebp) + # stdcall functions pop arguments off the stack themselves + # Load %ecx with the return type code movl 20(%ebp),%ecx @@ -181,164 +541,11 @@ movl %ebp,%esp popl %ebp ret -.ffi_call_SYSV_end: +.ffi_call_win32_end: .LFE1: # This assumes we are using gas. .balign 16 - .globl _ffi_call_STDCALL - .def _ffi_call_STDCALL; .scl 2; .type 32; .endef -_ffi_call_STDCALL: -.LFB2: - pushl %ebp -.LCFI2: - movl %esp,%ebp -.LCFI3: - # Make room for all of the new args. - movl 16(%ebp),%ecx - subl %ecx,%esp - - movl %esp,%eax - - # Place all of the ffi_prep_args in position - pushl 12(%ebp) - pushl %eax - call *8(%ebp) - - # Return stack to previous state and call the function - addl $8,%esp - - # FIXME: Align the stack to a 128-bit boundary to avoid - # potential performance hits. - - call *28(%ebp) - - # stdcall functions pop arguments off the stack themselves - - # Load %ecx with the return type code - movl 20(%ebp),%ecx - - # If the return value pointer is NULL, assume no return value. - cmpl $0,24(%ebp) - jne 0f - - # Even if there is no space for the return value, we are - # obliged to handle floating-point values. - cmpl $FFI_TYPE_FLOAT,%ecx - jne .Lsc_noretval - fstp %st(0) - - jmp .Lsc_epilogue - -0: - call 1f - # Do not insert anything here between the call and the jump table. -.Lsc_store_table: - .long .Lsc_noretval /* FFI_TYPE_VOID */ - .long .Lsc_retint /* FFI_TYPE_INT */ - .long .Lsc_retfloat /* FFI_TYPE_FLOAT */ - .long .Lsc_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lsc_retlongdouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lsc_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lsc_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lsc_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lsc_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lsc_retint /* FFI_TYPE_UINT32 */ - .long .Lsc_retint /* FFI_TYPE_SINT32 */ - .long .Lsc_retint64 /* FFI_TYPE_UINT64 */ - .long .Lsc_retint64 /* FFI_TYPE_SINT64 */ - .long .Lsc_retstruct /* FFI_TYPE_STRUCT */ - .long .Lsc_retint /* FFI_TYPE_POINTER */ - .long .Lsc_retstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lsc_retstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lsc_retstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */ - -1: - add %ecx, %ecx - add %ecx, %ecx - add (%esp),%ecx - add $4, %esp - jmp *(%ecx) - - /* Sign/zero extend as appropriate. */ -.Lsc_retsint8: - movsbl %al, %eax - jmp .Lsc_retint - -.Lsc_retsint16: - movswl %ax, %eax - jmp .Lsc_retint - -.Lsc_retuint8: - movzbl %al, %eax - jmp .Lsc_retint - -.Lsc_retuint16: - movzwl %ax, %eax - jmp .Lsc_retint - -.Lsc_retint: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp .Lsc_epilogue - -.Lsc_retfloat: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstps (%ecx) - jmp .Lsc_epilogue - -.Lsc_retdouble: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpl (%ecx) - jmp .Lsc_epilogue - -.Lsc_retlongdouble: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpt (%ecx) - jmp .Lsc_epilogue - -.Lsc_retint64: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - movl %edx,4(%ecx) - jmp .Lsc_epilogue - -.Lsc_retstruct1b: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movb %al,0(%ecx) - jmp .Lsc_epilogue - -.Lsc_retstruct2b: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movw %ax,0(%ecx) - jmp .Lsc_epilogue - -.Lsc_retstruct4b: - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp .Lsc_epilogue - -.Lsc_retstruct: - # Nothing to do! - -.Lsc_noretval: -.Lsc_epilogue: - movl %ebp,%esp - popl %ebp - ret -.ffi_call_STDCALL_end: -.LFE2: - - # This assumes we are using gas. - .balign 16 .globl _ffi_closure_SYSV .def _ffi_closure_SYSV; .scl 2; .type 32; .endef _ffi_closure_SYSV: @@ -742,38 +949,6 @@ .LEFDE1: -.LSFDE2: - .long .LEFDE2-.LASFDE2 /* FDE Length */ -.LASFDE2: - .long .LASFDE2-.Lframe1 /* FDE CIE offset */ -#if defined __PIC__ && defined HAVE_AS_X86_PCREL - .long .LFB2-. /* FDE initial location */ -#else - .long .LFB2 -#endif - .long .LFE2-.LFB2 /* FDE address range */ -#ifdef __PIC__ - .byte 0x0 /* .uleb128 0x0; Augmentation size */ -#endif - /* DW_CFA_xxx CFI instructions go here. */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .long .LCFI2-.LFB2 - .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */ - .byte 0x8 /* .uleb128 0x8 */ - .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */ - .byte 0x2 /* .uleb128 0x2 */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .long .LCFI3-.LCFI2 - .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */ - .byte 0x5 /* .uleb128 0x5 */ - - /* End of DW_CFA_xxx CFI instructions. */ - .align 4 -.LEFDE2: - - .LSFDE3: .long .LEFDE3-.LASFDE3 /* FDE Length */ .LASFDE3: @@ -875,3 +1050,6 @@ /* End of DW_CFA_xxx CFI instructions. */ .align 4 .LEFDE5: + +#endif /* !_MSC_VER */ + Index: Modules/_ctypes/libffi/src/x86/ffi.c =================================================================== --- Modules/_ctypes/libffi/src/x86/ffi.c (revision 79097) +++ Modules/_ctypes/libffi/src/x86/ffi.c (working copy) @@ -148,13 +148,13 @@ /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { + unsigned int i; + ffi_type **ptr; + /* Set the return type flag */ switch (cif->rtype->type) { case FFI_TYPE_VOID: -#ifdef X86 - case FFI_TYPE_STRUCT: -#endif #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64) case FFI_TYPE_UINT8: case FFI_TYPE_UINT16: @@ -165,7 +165,6 @@ case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: #endif - case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: @@ -184,8 +183,8 @@ cif->flags = FFI_TYPE_SINT64; break; -#ifndef X86 case FFI_TYPE_STRUCT: +#ifndef X86 if (cif->rtype->size == 1) { cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ @@ -207,15 +206,13 @@ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ } else +#endif { cif->flags = FFI_TYPE_STRUCT; -#ifdef X86_WIN64 // allocate space for return value pointer cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); -#endif } break; -#endif default: #ifdef X86_WIN64 @@ -229,41 +226,36 @@ break; } -#ifdef X86_DARWIN - cif->bytes = (cif->bytes + 15) & ~0xF; -#endif + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + if (((*ptr)->alignment - 1) & cif->bytes) + cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment); + cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG); + } #ifdef X86_WIN64 - { - unsigned int i; - ffi_type **ptr; - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - if (((*ptr)->alignment - 1) & cif->bytes) - cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment); - cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG); - } - } // ensure space for storing four registers cif->bytes += 4 * sizeof(ffi_arg); #endif +#ifdef X86_DARWIN + cif->bytes = (cif->bytes + 15) & ~0xF; +#endif + return FFI_OK; } -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, - unsigned, unsigned, unsigned *, void (*fn)(void)); - -#ifdef X86_WIN32 -extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, - unsigned, unsigned, unsigned *, void (*fn)(void)); - -#endif /* X86_WIN32 */ #ifdef X86_WIN64 extern int ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned *, void (*fn)(void)); +#elif defined(X86_WIN32) +extern void +ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)(void)); +#else +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)(void)); #endif void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) @@ -321,18 +313,18 @@ cif->flags, ecif.rvalue, fn); } break; +#elif defined(X86_WIN32) + case FFI_SYSV: + case FFI_STDCALL: + ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; #else case FFI_SYSV: ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; -#ifdef X86_WIN32 - case FFI_STDCALL: - ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#endif /* X86_WIN32 */ -#endif /* X86_WIN64 */ +#endif default: FFI_ASSERT(0); break; @@ -342,6 +334,8 @@ /** private members **/ +/* The following __attribute__((regparm(1))) decorations will have no effect + on MSVC - standard cdecl convention applies. */ static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) @@ -390,11 +384,8 @@ } #else -unsigned int FFI_HIDDEN -ffi_closure_SYSV_inner (closure, respp, args) - ffi_closure *closure; - void **respp; - void *args; +unsigned int FFI_HIDDEN __attribute__ ((regparm(1))) +ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args) { /* our various things... */ ffi_cif *cif; @@ -505,7 +496,7 @@ /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ -({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - (__ctx + 10); \ @@ -513,10 +504,10 @@ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned char *) &__tramp[5] = 0xe9; \ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ - }) + } #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ -({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - (__ctx + 10); \ @@ -527,7 +518,7 @@ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ *(unsigned char *) &__tramp[10] = 0xc2; \ *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \ - }) + } /* the cif must already be prep'ed */ @@ -595,9 +586,9 @@ } /* we currently don't support certain kinds of arguments for raw - // closures. This should be implemented by a separate assembly language - // routine, since it would require argument processing, something we - // don't do now for performance. */ + closures. This should be implemented by a separate assembly + language routine, since it would require argument processing, + something we don't do now for performance. */ for (i = cif->nargs-1; i >= 0; i--) { @@ -627,16 +618,6 @@ * libffi-1.20, this is not the case.) */ -extern void -ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)(void)); - -#ifdef X86_WIN32 -extern void -ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)(void)); -#endif /* X86_WIN32 */ - void ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) { @@ -660,16 +641,18 @@ switch (cif->abi) { +#ifdef X86_WIN32 case FFI_SYSV: + case FFI_STDCALL: + ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; +#else + case FFI_SYSV: ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; -#ifdef X86_WIN32 - case FFI_STDCALL: - ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#endif /* X86_WIN32 */ +#endif default: FFI_ASSERT(0); break; Index: Modules/_ctypes/libffi/src/mips/n32.S =================================================================== --- Modules/_ctypes/libffi/src/mips/n32.S (revision 79097) +++ Modules/_ctypes/libffi/src/mips/n32.S (working copy) @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - n32.S - Copyright (c) 1996, 1998, 2005 Red Hat, Inc. + n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010 Red Hat, Inc. MIPS Foreign Function Interface @@ -40,7 +40,7 @@ #define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG ) -#ifdef linux +#ifdef __GNUC__ .abicalls #endif .text @@ -529,7 +529,7 @@ .LFE2: .end ffi_closure_N32 -#ifdef linux +#ifdef __GNUC__ .section .eh_frame,"aw",@progbits .Lframe1: .4byte .LECIE1-.LSCIE1 # length @@ -586,6 +586,6 @@ .uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4 .align EH_FRAME_ALIGN .LEFDE3: -#endif /* linux */ +#endif /* __GNUC__ */ #endif Index: Modules/_ctypes/libffi/src/prep_cif.c =================================================================== --- Modules/_ctypes/libffi/src/prep_cif.c (revision 79097) +++ Modules/_ctypes/libffi/src/prep_cif.c (working copy) @@ -109,16 +109,13 @@ /* Perform a sanity check on the return type */ FFI_ASSERT_VALID_TYPE(cif->rtype); - /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA + /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */ +#if !defined M68K && !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA /* Make space for the return structure pointer */ if (cif->rtype->type == FFI_TYPE_STRUCT #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif -#ifdef X86_DARWIN - && (cif->rtype->size > 8) -#endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif @@ -134,7 +131,7 @@ check after the initialization. */ FFI_ASSERT_VALID_TYPE(*ptr); -#if !defined __x86_64__ && !defined S390 && !defined PA +#if !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA #ifdef SPARC if (((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 16 || cif->abi != FFI_V9)) Index: Modules/_ctypes/libffi/configure.ac =================================================================== --- Modules/_ctypes/libffi/configure.ac (revision 79098) +++ Modules/_ctypes/libffi/configure.ac (working copy) @@ -5,7 +5,7 @@ AC_PREREQ(2.63) -AC_INIT([libffi], [3.0.9], [http://gcc.gnu.org/bugs.html]) +AC_INIT([libffi], [3.0.10rc0], [http://gcc.gnu.org/bugs.html]) AC_CONFIG_HEADERS([fficonfig.h]) AC_CANONICAL_SYSTEM @@ -58,6 +58,10 @@ TARGET=X86_64; TARGETDIR=x86 ;; + amd64-*-freebsd*) + TARGET=X86_64; TARGETDIR=x86 + ;; + avr32*-*-*) TARGET=AVR32; TARGETDIR=avr32 ;; Index: Modules/_ctypes/libffi/doc/libffi.texi =================================================================== --- Modules/_ctypes/libffi/doc/libffi.texi (revision 79097) +++ Modules/_ctypes/libffi/doc/libffi.texi (working copy) @@ -19,7 +19,7 @@ This manual is for Libffi, a portable foreign-function interface library. -Copyright @copyright{} 2008 Red Hat, Inc. +Copyright @copyright{} 2008, 2010 Red Hat, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -106,6 +106,7 @@ * Types:: libffi type descriptions. * Multiple ABIs:: Different passing styles on one platform. * The Closure API:: Writing a generic function. +* Closure Example:: A closure example. @end menu @@ -500,13 +501,67 @@ to the appropriate pointer-to-function type. @end defun -@c FIXME: example - You may see old code referring to @code{ffi_prep_closure}. This function is deprecated, as it cannot handle the need for separate writable and executable addresses. +@node Closure Example +@section Closure Example +A trivial example that creates a new @code{puts} by binding +@code{fputs} with @code{stdin}. + +@example +#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; +@} + +@end example + + @node Missing Features @chapter Missing Features @@ -525,6 +580,8 @@ @item The closure API is +@c FIXME: ... + @item The ``raw'' API is undocumented. @c argument promotion? Index: Modules/_ctypes/libffi/doc/stamp-vti =================================================================== --- Modules/_ctypes/libffi/doc/stamp-vti (revision 79097) +++ Modules/_ctypes/libffi/doc/stamp-vti (working copy) @@ -1,4 +1,4 @@ -@set UPDATED 29 December 2009 -@set UPDATED-MONTH December 2009 -@set EDITION 3.0.9 -@set VERSION 3.0.9 +@set UPDATED 14 February 2008 +@set UPDATED-MONTH February 2008 +@set EDITION 3.0.8 +@set VERSION 3.0.8 Index: Modules/_ctypes/libffi/doc/libffi.info =================================================================== --- Modules/_ctypes/libffi/doc/libffi.info (revision 79097) +++ Modules/_ctypes/libffi/doc/libffi.info (working copy) @@ -4,7 +4,7 @@ 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 @@ -27,7 +27,7 @@ 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 @@ * 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 @@ -368,7 +369,7 @@ 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 +445,62 @@ 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 @@ -516,18 +573,19 @@  Tag Table: -Node: Top700 -Node: Introduction1436 -Node: Using libffi3072 -Node: The Basics3507 -Node: Simple Example6114 -Node: Types7141 -Node: Primitive Types7424 -Node: Structures9244 -Node: Type Example10104 -Node: Multiple ABIs11327 -Node: The Closure API11698 -Node: Missing Features14618 -Node: Index15111 +Node: Top706 +Node: Introduction1448 +Node: Using libffi3084 +Node: The Basics3570 +Node: Simple Example6177 +Node: Types7204 +Node: Primitive Types7487 +Node: Structures9307 +Node: Type Example10167 +Node: Multiple ABIs11390 +Node: The Closure API11761 +Node: Closure Example14705 +Node: Missing Features16264 +Node: Index16757  End Tag Table Index: Modules/_ctypes/libffi/doc/version.texi =================================================================== --- Modules/_ctypes/libffi/doc/version.texi (revision 79097) +++ Modules/_ctypes/libffi/doc/version.texi (working copy) @@ -1,4 +1,4 @@ -@set UPDATED 29 December 2009 -@set UPDATED-MONTH December 2009 -@set EDITION 3.0.9 -@set VERSION 3.0.9 +@set UPDATED 14 February 2008 +@set UPDATED-MONTH February 2008 +@set EDITION 3.0.8 +@set VERSION 3.0.8 Index: Modules/_ctypes/libffi/include/ffi.h.in =================================================================== --- Modules/_ctypes/libffi/include/ffi.h.in (revision 79097) +++ Modules/_ctypes/libffi/include/ffi.h.in (working copy) @@ -251,6 +251,9 @@ #if FFI_CLOSURES +#ifdef _MSC_VER +__declspec(align(8)) +#endif typedef struct { char tramp[FFI_TRAMPOLINE_SIZE]; ffi_cif *cif; Index: Modules/_ctypes/libffi/ChangeLog =================================================================== --- Modules/_ctypes/libffi/ChangeLog (revision 79097) +++ Modules/_ctypes/libffi/ChangeLog (working copy) @@ -1,3 +1,89 @@ +2010-03-14 Matthias Klose + + * src/x86/ffi64.c: Fix typo in comment. + * src/x86/ffi.c: Use /* ... */ comment style. + +2010-01-07 Rainer Orth + + PR libffi/40701 + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL, + PRIuLL, PRId64, PRIu64, PRIuPTR): Define. + * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on + alpha*-dec-osf*. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/return_ll1.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast + MAP_FAILED to char *. + +2010-01-06 Rainer Orth + + * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__. + +2009-12-31 Anthony Green + + * README: Update for libffi 3.0.9. + +2009-12-27 Matthias Klose + + * configure.ac (HAVE_LONG_DOUBLE): Define for mips when + appropriate. + * configure: Rebuilt. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for + avr32*-*-*. + * testsuite/libffi.call/cls_double_va.c: Ditto. + +2009-12-26 Andreas Tobler + + * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h + and inttypes.h. + * testsuite/libffi.special/unwindtest.cc: Ditto. + +2009-12-26 Andreas Tobler + + * configure.ac: Add amd64-*-openbsd*. + * configure: Rebuilt. + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link + openbsd programs with -lpthread. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for + mips*-*-* and arm*-*-*. + * testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. + +2009-12-31 Kay Tietz + + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix + definitions. + +2009-12-31 Carlo Bramini + + * configure.ac (AM_LTLDFLAGS): Define for windows hosts. + * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + +2009-12-31 Anthony Green + Blake Chaffin. + + * testsuite/libffi.call/huge_struct.c: New test case from Blake + Chaffin @ Apple. + 2009-12-28 David Edelsohn * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to Index: Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c (working copy) @@ -5,6 +5,7 @@ Originator: 20031203 */ /* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ #include "ffitest.h" typedef struct cls_struct_align { Index: Modules/_ctypes/libffi/testsuite/libffi.call/return_ll1.c =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/return_ll1.c (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/return_ll1.c (working copy) @@ -5,6 +5,7 @@ Originator: 20050222 */ /* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ #include "ffitest.h" static long long return_ll(int ll0, long long ll1, int ll2) { Index: Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble.c =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble.c (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble.c (working copy) @@ -5,7 +5,7 @@ Originator: Blake Chaffin */ /* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ -/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-do run { xfail arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ /* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */ Index: Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c (working copy) @@ -6,6 +6,7 @@ /* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ #include "ffitest.h" typedef struct cls_struct_align { Index: Modules/_ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c (working copy) @@ -5,6 +5,7 @@ Originator: 20030828 */ /* { dg-do run } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ #include "ffitest.h" static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp, Index: Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h (working copy) @@ -60,6 +60,18 @@ #define PRIuLL "llu" #endif +/* Tru64 UNIX kludge. */ +#if defined(__alpha__) && defined(__osf__) +/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */ +#undef PRIdLL +#define PRIdLL "ld" +#undef PRIuLL +#define PRIuLL "lu" +#define PRId64 "ld" +#define PRIu64 "lu" +#define PRIuPTR "lu" +#endif + /* PA HP-UX kludge. */ #if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR) #define PRIuPTR "lu" Index: Modules/_ctypes/libffi/testsuite/libffi.call/stret_medium2.c =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.call/stret_medium2.c (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.call/stret_medium2.c (working copy) @@ -7,6 +7,7 @@ Originator: Blake Chaffin 6/21/2007 */ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ +/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ #include "ffitest.h" typedef struct struct_72byte { Index: Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp =================================================================== --- Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp (revision 79097) +++ Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp (working copy) @@ -1,8 +1,8 @@ -# Copyright (C) 2003, 2005, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, Index: Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h =================================================================== --- Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h (revision 79097) +++ Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h (working copy) @@ -84,7 +84,7 @@ MAP_PRIVATE, dev_zero_fd, 0); #endif - if (page == MAP_FAILED) + if (page == (char *) MAP_FAILED) { perror ("virtual memory exhausted"); exit (1); Index: Modules/_ctypes/libffi/README =================================================================== --- Modules/_ctypes/libffi/README (revision 79097) +++ Modules/_ctypes/libffi/README (working copy) @@ -1,7 +1,7 @@ Status ====== -libffi-3.0.9 was released on December 31, 2009. Check the libffi web +libffi-3.0.10 was released on XXXXXXXXXX, 2010. Check the libffi web page for updates: . @@ -43,7 +43,7 @@ For specific configuration details and testing status, please refer to the wiki page here: - http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.9 + http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.10 At the time of release, the following basic configurations have been tested: @@ -52,6 +52,7 @@ | Architecture | Operating System | |--------------+------------------| | Alpha | Linux | +| Alpha | Tru64 | | ARM | Linux | | AVR32 | Linux | | HPPA | HPUX | @@ -80,6 +81,7 @@ | X86-64 | FreeBSD | | X86-64 | Linux | | X86-64 | OpenBSD | +| X86-64 | Windows/MingW | |--------------+------------------| Please send additional platform test results to @@ -107,6 +109,14 @@ are using Purify with libffi. Only use this switch when using Purify, as it will slow down the library. +It's also possible to build libffi on Windows platforms with +Microsoft's Visual C++ compiler. In this case, use the msvcc.sh +wrapper script during configuration like so: + +path/to/configure --enable-shared --enable-static \ + CC=path/to/msvcc.sh LD=link \ + CPP=\"cl -nologo -EP\" + Configure has many other options. Use "configure --help" to see them all. Once configure has finished, type "make". Note that you must be using @@ -123,6 +133,12 @@ See the ChangeLog files for details. +3.0.10 ???-??-?? + Fix the N64 build on mips-sgi-irix6.5. + Testsuite fixes for Tru64 Unix. + Enable builds with Microsoft's compiler. + Enable x86 builds with Sun's compiler. + 3.0.9 Dec-31-09 Add AVR32 and win64 ports. Add ARM softfp support. Many fixes for AIX, Solaris, HP-UX, *BSD. Index: Modules/_ctypes/libffi/Makefile.am =================================================================== --- Modules/_ctypes/libffi/Makefile.am (revision 79097) +++ Modules/_ctypes/libffi/Makefile.am (working copy) @@ -175,7 +175,7 @@ AM_CFLAGS = -Wall -g -fexceptions -libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(AM_LTLDFLAGS) +libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) @@ -184,4 +184,3 @@ .PHONY: install-html install-pdf install-html: install-pdf: - Index: Modules/_ctypes/libffi.diff =================================================================== --- Modules/_ctypes/libffi.diff (revision 79098) +++ Modules/_ctypes/libffi.diff (working copy) @@ -111,31 +111,3 @@ +AC_CONFIG_FILES(fficonfig.py) + AC_OUTPUT -diff -urN libffi.orig/src/x86/ffi64.c libffi/src/x86/ffi64.c ---- libffi.orig/src/x86/ffi64.c 2010-03-19 18:27:45.008523897 +0100 -+++ libffi/src/x86/ffi64.c 2010-03-19 18:24:36.437500070 +0100 -@@ -52,7 +52,7 @@ - /* Register class used for passing given 64bit part of the argument. - These represent classes as documented by the PS ABI, with the exception - of SSESF, SSEDF classes, that are basically SSE class, just gcc will -- use SF or DFmode move instead of DImode to avoid reformating penalties. -+ use SF or DFmode move instead of DImode to avoid reformatting penalties. - - Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves - whenever possible (upper half does contain padding). */ -diff -urN libffi.orig/src/x86/ffi.c libffi/src/x86/ffi.c ---- libffi.orig/src/x86/ffi.c 2010-03-19 18:27:45.008523897 +0100 -+++ libffi/src/x86/ffi.c 2010-03-19 18:24:36.441496039 +0100 -@@ -594,10 +594,10 @@ - return FFI_BAD_ABI; - } - -- // we currently don't support certain kinds of arguments for raw -+ /* we currently don't support certain kinds of arguments for raw - // closures. This should be implemented by a separate assembly language - // routine, since it would require argument processing, something we -- // don't do now for performance. -+ // don't do now for performance. */ - - for (i = cif->nargs-1; i >= 0; i--) - {