Issue #27355: Removed support for Windows CE. It was never finished,

and Windows CE is no longer a relevant platform for Python.
This commit is contained in:
Larry Hastings 2016-09-05 15:11:23 -07:00
parent 8c21ab0ab9
commit 10108a7b9a
27 changed files with 28 additions and 1549 deletions

View File

@ -57,7 +57,7 @@ Notes on the availability of these functions:
The name of the operating system dependent module imported. The following The name of the operating system dependent module imported. The following
names have currently been registered: ``'posix'``, ``'nt'``, names have currently been registered: ``'posix'``, ``'nt'``,
``'ce'``, ``'java'``. ``'java'``.
.. seealso:: .. seealso::
:attr:`sys.platform` has a finer granularity. :func:`os.uname` gives :attr:`sys.platform` has a finer granularity. :func:`os.uname` gives

View File

@ -20,7 +20,7 @@ These modules are used to implement the :mod:`os.path` module, and are not
documented beyond this mention. There's little need to document these. documented beyond this mention. There's little need to document these.
:mod:`ntpath` :mod:`ntpath`
--- Implementation of :mod:`os.path` on Win32, Win64, and WinCE platforms. --- Implementation of :mod:`os.path` on Win32 and Win64 platforms.
:mod:`posixpath` :mod:`posixpath`
--- Implementation of :mod:`os.path` on POSIX. --- Implementation of :mod:`os.path` on POSIX.

View File

@ -333,7 +333,7 @@ class dispatcher:
self.connecting = True self.connecting = True
err = self.socket.connect_ex(address) err = self.socket.connect_ex(address)
if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \ if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \
or err == EINVAL and os.name in ('nt', 'ce'): or err == EINVAL and os.name == 'nt':
self.addr = address self.addr = address
return return
if err in (0, EISCONN): if err in (0, EISCONN):

View File

@ -16,7 +16,7 @@ from struct import calcsize as _calcsize
if __version__ != _ctypes_version: if __version__ != _ctypes_version:
raise Exception("Version number mismatch", __version__, _ctypes_version) raise Exception("Version number mismatch", __version__, _ctypes_version)
if _os.name in ("nt", "ce"): if _os.name == "nt":
from _ctypes import FormatError from _ctypes import FormatError
DEFAULT_MODE = RTLD_LOCAL DEFAULT_MODE = RTLD_LOCAL
@ -103,12 +103,9 @@ def CFUNCTYPE(restype, *argtypes, **kw):
_c_functype_cache[(restype, argtypes, flags)] = CFunctionType _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
return CFunctionType return CFunctionType
if _os.name in ("nt", "ce"): if _os.name == "nt":
from _ctypes import LoadLibrary as _dlopen from _ctypes import LoadLibrary as _dlopen
from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
if _os.name == "ce":
# 'ce' doesn't have the stdcall calling convention
_FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
_win_functype_cache = {} _win_functype_cache = {}
def WINFUNCTYPE(restype, *argtypes, **kw): def WINFUNCTYPE(restype, *argtypes, **kw):
@ -262,7 +259,7 @@ class c_wchar(_SimpleCData):
def _reset_cache(): def _reset_cache():
_pointer_type_cache.clear() _pointer_type_cache.clear()
_c_functype_cache.clear() _c_functype_cache.clear()
if _os.name in ("nt", "ce"): if _os.name == "nt":
_win_functype_cache.clear() _win_functype_cache.clear()
# _SimpleCData.c_wchar_p_from_param # _SimpleCData.c_wchar_p_from_param
POINTER(c_wchar).from_param = c_wchar_p.from_param POINTER(c_wchar).from_param = c_wchar_p.from_param
@ -374,7 +371,7 @@ class PyDLL(CDLL):
""" """
_func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
if _os.name in ("nt", "ce"): if _os.name == "nt":
class WinDLL(CDLL): class WinDLL(CDLL):
"""This class represents a dll exporting functions using the """This class represents a dll exporting functions using the
@ -427,7 +424,7 @@ class LibraryLoader(object):
cdll = LibraryLoader(CDLL) cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL) pydll = LibraryLoader(PyDLL)
if _os.name in ("nt", "ce"): if _os.name == "nt":
pythonapi = PyDLL("python dll", None, _sys.dllhandle) pythonapi = PyDLL("python dll", None, _sys.dllhandle)
elif _sys.platform == "cygwin": elif _sys.platform == "cygwin":
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
@ -435,7 +432,7 @@ else:
pythonapi = PyDLL(None) pythonapi = PyDLL(None)
if _os.name in ("nt", "ce"): if _os.name == "nt":
windll = LibraryLoader(WinDLL) windll = LibraryLoader(WinDLL)
oledll = LibraryLoader(OleDLL) oledll = LibraryLoader(OleDLL)
@ -503,7 +500,7 @@ else:
return _wstring_at(ptr, size) return _wstring_at(ptr, size)
if _os.name in ("nt", "ce"): # COM stuff if _os.name == "nt": # COM stuff
def DllGetClassObject(rclsid, riid, ppv): def DllGetClassObject(rclsid, riid, ppv):
try: try:
ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])

View File

@ -196,7 +196,7 @@ class BitFieldTest(unittest.TestCase):
class X(Structure): class X(Structure):
_fields_ = [("a", c_byte, 4), _fields_ = [("a", c_byte, 4),
("b", c_int, 4)] ("b", c_int, 4)]
if os.name in ("nt", "ce"): if os.name == "nt":
self.assertEqual(sizeof(X), sizeof(c_int)*2) self.assertEqual(sizeof(X), sizeof(c_int)*2)
else: else:
self.assertEqual(sizeof(X), sizeof(c_int)) self.assertEqual(sizeof(X), sizeof(c_int))
@ -224,7 +224,7 @@ class BitFieldTest(unittest.TestCase):
# MSVC does NOT combine c_short and c_int into one field, GCC # MSVC does NOT combine c_short and c_int into one field, GCC
# does (unless GCC is run with '-mms-bitfields' which # does (unless GCC is run with '-mms-bitfields' which
# produces code compatible with MSVC). # produces code compatible with MSVC).
if os.name in ("nt", "ce"): if os.name == "nt":
self.assertEqual(sizeof(X), sizeof(c_int) * 4) self.assertEqual(sizeof(X), sizeof(c_int) * 4)
else: else:
self.assertEqual(sizeof(X), sizeof(c_int) * 2) self.assertEqual(sizeof(X), sizeof(c_int) * 2)

View File

@ -39,7 +39,7 @@ class CFuncPtrTestCase(unittest.TestCase):
# possible, as in C, to call cdecl functions with more parameters. # possible, as in C, to call cdecl functions with more parameters.
#self.assertRaises(TypeError, c, 1, 2, 3) #self.assertRaises(TypeError, c, 1, 2, 3)
self.assertEqual(c(1, 2, 3, 4, 5, 6), 3) self.assertEqual(c(1, 2, 3, 4, 5, 6), 3)
if not WINFUNCTYPE is CFUNCTYPE and os.name != "ce": if not WINFUNCTYPE is CFUNCTYPE:
self.assertRaises(TypeError, s, 1, 2, 3) self.assertRaises(TypeError, s, 1, 2, 3)
def test_structures(self): def test_structures(self):

View File

@ -11,8 +11,6 @@ def setUpModule():
global libc_name global libc_name
if os.name == "nt": if os.name == "nt":
libc_name = find_library("c") libc_name = find_library("c")
elif os.name == "ce":
libc_name = "coredll"
elif sys.platform == "cygwin": elif sys.platform == "cygwin":
libc_name = "cygwin1.dll" libc_name = "cygwin1.dll"
else: else:
@ -49,8 +47,8 @@ class LoaderTest(unittest.TestCase):
cdll.LoadLibrary(lib) cdll.LoadLibrary(lib)
CDLL(lib) CDLL(lib)
@unittest.skipUnless(os.name in ("nt", "ce"), @unittest.skipUnless(os.name == "nt",
'test specific to Windows (NT/CE)') 'test specific to Windows')
def test_load_library(self): def test_load_library(self):
# CRT is no longer directly loadable. See issue23606 for the # CRT is no longer directly loadable. See issue23606 for the
# discussion about alternative approaches. # discussion about alternative approaches.
@ -64,14 +62,9 @@ class LoaderTest(unittest.TestCase):
windll["kernel32"].GetModuleHandleW windll["kernel32"].GetModuleHandleW
windll.LoadLibrary("kernel32").GetModuleHandleW windll.LoadLibrary("kernel32").GetModuleHandleW
WinDLL("kernel32").GetModuleHandleW WinDLL("kernel32").GetModuleHandleW
elif os.name == "ce":
windll.coredll.GetModuleHandleW
windll["coredll"].GetModuleHandleW
windll.LoadLibrary("coredll").GetModuleHandleW
WinDLL("coredll").GetModuleHandleW
@unittest.skipUnless(os.name in ("nt", "ce"), @unittest.skipUnless(os.name == "nt",
'test specific to Windows (NT/CE)') 'test specific to Windows')
def test_load_ordinal_functions(self): def test_load_ordinal_functions(self):
import _ctypes_test import _ctypes_test
dll = WinDLL(_ctypes_test.__file__) dll = WinDLL(_ctypes_test.__file__)

View File

@ -67,16 +67,6 @@ if os.name == "nt":
return fname return fname
return None return None
if os.name == "ce":
# search path according to MSDN:
# - absolute path specified by filename
# - The .exe launch directory
# - the Windows directory
# - ROM dll files (where are they?)
# - OEM specified search path: HKLM\Loader\SystemPath
def find_library(name):
return name
if os.name == "posix" and sys.platform == "darwin": if os.name == "posix" and sys.platform == "darwin":
from ctypes.macholib.dyld import dyld_find as _dyld_find from ctypes.macholib.dyld import dyld_find as _dyld_find
def find_library(name): def find_library(name):

View File

@ -28,8 +28,6 @@ sep = '\\'
pathsep = ';' pathsep = ';'
altsep = '/' altsep = '/'
defpath = '.;C:\\bin' defpath = '.;C:\\bin'
if 'ce' in sys.builtin_module_names:
defpath = '\\Windows'
devnull = 'nul' devnull = 'nul'
def _get_bothseps(path): def _get_bothseps(path):

View File

@ -1,9 +1,9 @@
r"""OS routines for NT or Posix depending on what system we're on. r"""OS routines for NT or Posix depending on what system we're on.
This exports: This exports:
- all functions from posix, nt or ce, e.g. unlink, stat, etc. - all functions from posix or nt, e.g. unlink, stat, etc.
- os.path is either posixpath or ntpath - os.path is either posixpath or ntpath
- os.name is either 'posix', 'nt' or 'ce'. - os.name is either 'posix' or 'nt'
- os.curdir is a string representing the current directory ('.' or ':') - os.curdir is a string representing the current directory ('.' or ':')
- os.pardir is a string representing the parent directory ('..' or '::') - os.pardir is a string representing the parent directory ('..' or '::')
- os.sep is the (or a most common) pathname separator ('/' or ':' or '\\') - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
@ -85,27 +85,6 @@ elif 'nt' in _names:
except ImportError: except ImportError:
pass pass
elif 'ce' in _names:
name = 'ce'
linesep = '\r\n'
from ce import *
try:
from ce import _exit
__all__.append('_exit')
except ImportError:
pass
# We can use the standard Windows path.
import ntpath as path
import ce
__all__.extend(_get_exports_list(ce))
del ce
try:
from ce import _have_functions
except ImportError:
pass
else: else:
raise ImportError('no os specific module found') raise ImportError('no os specific module found')

View File

@ -13,7 +13,6 @@
# Python bug tracker (http://bugs.python.org) and assign them to "lemburg". # Python bug tracker (http://bugs.python.org) and assign them to "lemburg".
# #
# Still needed: # Still needed:
# * more support for WinCE
# * support for MS-DOS (PythonDX ?) # * support for MS-DOS (PythonDX ?)
# * support for Amiga and other still unsupported platforms running Python # * support for Amiga and other still unsupported platforms running Python
# * support for additional Linux distributions # * support for additional Linux distributions

View File

@ -144,7 +144,7 @@ PAX_NUMBER_FIELDS = {
#--------------------------------------------------------- #---------------------------------------------------------
# initialization # initialization
#--------------------------------------------------------- #---------------------------------------------------------
if os.name in ("nt", "ce"): if os.name == "nt":
ENCODING = "utf-8" ENCODING = "utf-8"
else: else:
ENCODING = sys.getfilesystemencoding() ENCODING = sys.getfilesystemencoding()

View File

@ -811,7 +811,7 @@ TESTFN_ENCODING = sys.getfilesystemencoding()
# encoded by the filesystem encoding (in strict mode). It can be None if we # encoded by the filesystem encoding (in strict mode). It can be None if we
# cannot generate such filename. # cannot generate such filename.
TESTFN_UNENCODABLE = None TESTFN_UNENCODABLE = None
if os.name in ('nt', 'ce'): if os.name == 'nt':
# skip win32s (0) or Windows 9x/ME (1) # skip win32s (0) or Windows 9x/ME (1)
if sys.getwindowsversion().platform >= 2: if sys.getwindowsversion().platform >= 2:
# Different kinds of characters from various languages to minimize the # Different kinds of characters from various languages to minimize the

View File

@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 1
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #27355: Removed support for Windows CE. It was never finished,
and Windows CE is no longer a relevant platform for Python.
- Issue #27921: Disallow backslashes in f-strings. This is a temporary - Issue #27921: Disallow backslashes in f-strings. This is a temporary
restriction: in beta 2, backslashes will only be disallowed inside restriction: in beta 2, backslashes will only be disallowed inside
the braces (where the expressions are). This is a breaking change the braces (where the expressions are). This is a breaking change

View File

@ -111,12 +111,6 @@ bytes(cdata)
#ifndef IS_INTRESOURCE #ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0) #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
#endif #endif
# ifdef _WIN32_WCE
/* Unlike desktop Windows, WinCE has both W and A variants of
GetProcAddress, but the default W version is not what we want */
# undef GetProcAddress
# define GetProcAddress GetProcAddressA
# endif
#else #else
#include "ctypes_dlfcn.h" #include "ctypes_dlfcn.h"
#endif #endif

View File

@ -1,59 +0,0 @@
/* -----------------------------------------------------------------------
debug.c - Copyright (c) 1996 Red Hat, Inc.
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 CYGNUS SOLUTIONS 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 <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#include <stdio.h>
/* General debugging routines */
void ffi_stop_here(void)
{
/* This function is only useful for debugging purposes.
Place a breakpoint on ffi_stop_here to be notified of
significant events. */
}
/* This function should only be called via the FFI_ASSERT() macro */
void ffi_assert(char *expr, char *file, int line)
{
fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);
ffi_stop_here();
abort();
}
/* Perform a sanity check on an ffi_type structure */
void ffi_type_test(ffi_type *a, char *file, int line)
{
FFI_ASSERT_AT(a != NULL, file, line);
/*@-usedef@*/
FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
/*@=usedef@*/
}

View File

@ -1,310 +0,0 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Red Hat, Inc.
ARM 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 CYGNUS SOLUTIONS 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 <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#ifdef _WIN32_WCE
#pragma warning (disable : 4142) /* benign redefinition of type */
#include <windows.h>
#endif
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
*(void **) argp = ecif->rvalue;
argp += 4;
}
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0);
i--, p_arg++)
{
size_t z;
size_t argalign = (*p_arg)->alignment;
#ifdef _WIN32_WCE
if (argalign > 4)
argalign = 4;
#endif
/* Align if necessary */
if ((argalign - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, argalign);
}
z = (*p_arg)->size;
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;
case FFI_TYPE_STRUCT:
/* *p_argv may not be aligned for a UINT32 */
memcpy(argp, *p_argv, z);
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;
}
return;
}
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
case FFI_TYPE_SINT64:
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_UINT64:
cif->flags = FFI_TYPE_SINT64;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
/*@-declundef@*/
/*@-exportheader@*/
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
/* Return type changed from void for ctypes */
int ffi_call(/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ 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))
{
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
}
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
/*@-usedef@*/
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;
default:
FFI_ASSERT(0);
break;
}
/* I think calculating the real stack pointer delta is not useful
because stdcall is not supported */
return 0;
}
/** private members **/
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
/* This function is called by ffi_closure_SYSV in sysv.asm */
unsigned int
ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
{
ffi_cif *cif = closure->cif;
void **out_args;
out_args = (void **) alloca(cif->nargs * sizeof (void *));
/* this call will initialize out_args, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
* a structure, it will re-set rvalue to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(in_args, &rvalue, out_args, cif);
(closure->fun)(cif, rvalue, out_args, closure->user_data);
/* Tell ffi_closure_SYSV what the returntype is */
return cif->flags;
}
/*@-exportheader@*/
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
void **avalue, ffi_cif *cif)
/*@=exportheader@*/
{
unsigned int i;
void **p_argv;
char *argp;
ffi_type **p_arg;
argp = stack;
if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
argp += 4;
}
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
size_t argalign = (*p_arg)->alignment;
#ifdef _WIN32_WCE
if (argalign > 4)
argalign = 4;
#endif
/* Align if necessary */
if ((argalign - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, argalign);
}
z = (*p_arg)->size;
if (z < sizeof(int))
z = sizeof(int);
*p_argv = (void*) argp;
p_argv++;
argp += z;
}
}
/*
add ip, pc, #-8 ; ip = address of this trampoline == address of ffi_closure
ldr pc, [pc, #-4] ; jump to __fun
DCD __fun
*/
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN) \
{ \
unsigned int *__tramp = (unsigned int *)(TRAMP); \
__tramp[0] = 0xe24fc008; /* add ip, pc, #-8 */ \
__tramp[1] = 0xe51ff004; /* ldr pc, [pc, #-4] */ \
__tramp[2] = (unsigned int)(FUN); \
}
/* the cif must already be prep'ed */
/* defined in sysv.asm */
void ffi_closure_SYSV(void);
ffi_status
ffi_prep_closure (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
#ifdef _WIN32_WCE
/* This is important to allow calling the trampoline safely */
FlushInstructionCache(GetCurrentProcess(), 0, 0);
#endif
return FFI_OK;
}

View File

@ -1,317 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
libffi 2.00-beta-wince - Copyright (c) 1996-2003 Red Hat, Inc.
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 CYGNUS SOLUTIONS 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.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
The basic API is described in the README file.
The raw API is designed to bypass some of the argument packing
and unpacking on architectures for which it can be avoided.
The closure API allows interpreted functions to be packaged up
inside a C function pointer, so that they can be called as C functions,
with no understanding on the client side that they are interpreted.
It can also be used in other cases in which it is necessary to package
up a user specified parameter and a function pointer as a single
function pointer.
The closure API must be implemented in order to get its functionality,
e.g. for use by gij. Routines are provided to emulate the raw API
if the underlying platform doesn't allow faster implementation.
More details on the raw and cloure API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Specify which architecture libffi is configured for. */
/*#define @TARGET@*/
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _MSC_VER
# define FFI_LONG_LONG_MAX _I64_MAX
# endif
# endif
#endif
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#define ffi_type_ulong ffi_type_uint64
#define ffi_type_slong ffi_type_sint64
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != 9223372036854775807
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != 9223372036854775807
#error "long size not supported"
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t */
/* can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
/*@null@*/ struct _ffi_type **elements;
} ffi_type;
/* These are defined in types.c */
extern ffi_type ffi_type_void;
extern ffi_type ffi_type_uint8;
extern ffi_type ffi_type_sint8;
extern ffi_type ffi_type_uint16;
extern ffi_type ffi_type_sint16;
extern ffi_type ffi_type_uint32;
extern ffi_type ffi_type_sint32;
extern ffi_type ffi_type_uint64;
extern ffi_type ffi_type_sint64;
extern ffi_type ffi_type_float;
extern ffi_type ffi_type_double;
extern ffi_type ffi_type_longdouble;
extern ffi_type ffi_type_pointer;
typedef enum {
FFI_OK = 0,
FFI_BAD_TYPEDEF,
FFI_BAD_ABI
} ffi_status;
typedef unsigned FFI_TYPE;
typedef struct {
ffi_abi abi;
unsigned nargs;
/*@dependent@*/ ffi_type **arg_types;
/*@dependent@*/ ffi_type *rtype;
unsigned bytes;
unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == 9223372036854775807
# define FFI_SIZEOF_ARG 8
# endif
#endif
typedef union {
ffi_sarg sint;
ffi_arg uint;
float flt;
char data[FFI_SIZEOF_ARG];
void* ptr;
} ffi_raw;
void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ ffi_raw *avalue);
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter */
/* packing, even on 64-bit machines. I.e. on 64-bit machines */
/* longs and doubles are followed by an empty 64-bit word. */
void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ ffi_raw *avalue);
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
} ffi_closure;
ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data);
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* if this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
void *user_data;
} ffi_raw_closure;
ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
ffi_status
ffi_prep_java_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
#endif /* FFI_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
/*@dependent@*/ ffi_type **atypes);
/* Return type changed from void for ctypes */
int ffi_call(/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue);
/* Useful for eliminating compiler warnings */
#define FFI_FN(f) ((void (*)())f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 0 /*@HAVE_LONG_DOUBLE@*/
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
/* This should always refer to the last type code (for sanity checks) */
#define FFI_TYPE_LAST FFI_TYPE_POINTER
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,111 +0,0 @@
/* -----------------------------------------------------------------------
ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
Common internal definitions and macros. Only necessary for building
libffi.
----------------------------------------------------------------------- */
#ifndef FFI_COMMON_H
#define FFI_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include <fficonfig.h>
/* Do not move this. Some versions of AIX are very picky about where
this is positioned. */
#ifdef __GNUC__
# define alloca __builtin_alloca
#else
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
/* Check for the existence of memcpy. */
#if STDC_HEADERS
# include <string.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#if defined(FFI_DEBUG)
#include <stdio.h>
#endif
#ifdef FFI_DEBUG
/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line);
void ffi_stop_here(void);
void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line);
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
#else
#define FFI_ASSERT(x)
#define FFI_ASSERT_AT(x, f, l)
#define FFI_ASSERT_VALID_TYPE(x)
#endif
#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
/* Extended cif, used in callback from assembly routine */
typedef struct
{
/*@dependent@*/ ffi_cif *cif;
/*@dependent@*/ void *rvalue;
/*@dependent@*/ void **avalue;
} extended_cif;
/* Terse sized type definitions. */
#if defined(__GNUC__)
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
typedef signed int SINT16 __attribute__((__mode__(__HI__)));
typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
#elif defined(_MSC_VER)
typedef unsigned __int8 UINT8;
typedef signed __int8 SINT8;
typedef unsigned __int16 UINT16;
typedef signed __int16 SINT16;
typedef unsigned __int32 UINT32;
typedef signed __int32 SINT32;
typedef unsigned __int64 UINT64;
typedef signed __int64 SINT64;
#else
#error "Need typedefs here"
#endif
typedef float FLOAT32;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,152 +0,0 @@
/* fficonfig.h created manually for Windows CE on ARM */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
#define BYTEORDER 1234
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
/* #undef EH_FRAME_FLAGS */
/* Define this if you want extra debugging. */
#ifdef DEBUG /* Defined by the project settings for Debug builds */
#define FFI_DEBUG
#else
#undef FFI_DEBUG
#endif
/* Define this is you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this is you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
/* #undef HAVE_ALLOCA_H */
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */
/* Define if you have the long double type and it is bigger than a double */
/* This differs from the MSVC build, but even there it should not be defined */
/* #undef HAVE_LONG_DOUBLE */
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <memory.h> header file. */
/* WinCE has this but I don't think we need to use it */
/* #undef HAVE_MEMORY_H */
/* Define to 1 if you have the `mmap' function. */
/* #undef HAVE_MMAP */
/* Define if mmap with MAP_ANON(YMOUS) works. */
/* #undef HAVE_MMAP_ANON */
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
/* #undef HAVE_MMAP_FILE */
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
/* #undef HAVE_SYS_STAT_H */
/* Define to 1 if you have the <sys/types.h> header file. */
/* #undef HAVE_SYS_TYPES_H */
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define if the host machine stores words of multi-word integers in
big-endian order. */
/* #undef HOST_WORDS_BIG_ENDIAN */
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
/* Name of package */
/* #undef PACKAGE */
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* The number of bytes in type double */
#define SIZEOF_DOUBLE 8
/* The number of bytes in type long double */
#define SIZEOF_LONG_DOUBLE 8
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
/* #undef VERSION */
/* whether byteorder is bigendian */
/* #undef WORDS_BIGENDIAN */
#define alloca _alloca
#define abort() exit(999)

View File

@ -1,49 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for ARM.
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 CYGNUS SOLUTIONS 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
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_SYSV,
FFI_DEFAULT_ABI = FFI_SYSV,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 12
#define FFI_NATIVE_RAW_API 0
#endif

View File

@ -1,175 +0,0 @@
/* -----------------------------------------------------------------------
prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc.
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 CYGNUS SOLUTIONS 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 <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* Round up to FFI_SIZEOF_ARG. */
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
/* Perform machine independent initialization of aggregate type
specifications. */
static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
{
ffi_type **ptr;
FFI_ASSERT(arg != NULL);
/*@-usedef@*/
FFI_ASSERT(arg->elements != NULL);
FFI_ASSERT(arg->size == 0);
FFI_ASSERT(arg->alignment == 0);
ptr = &(arg->elements[0]);
while ((*ptr) != NULL)
{
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
/* Perform a sanity check on the argument type */
FFI_ASSERT_VALID_TYPE(*ptr);
arg->size = ALIGN(arg->size, (*ptr)->alignment);
arg->size += (*ptr)->size;
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
ptr++;
}
/* Structure size includes tail padding. This is important for
structures that fit in one register on ABIs like the PowerPC64
Linux ABI that right justify small structs in a register.
It's also needed for nested structure layout, for example
struct A { long a; char b; }; struct B { struct A x; char y; };
should find y at an offset of 2*sizeof(long) and result in a
total size of 3*sizeof(long). */
arg->size = ALIGN (arg->size, arg->alignment);
if (arg->size == 0)
return FFI_BAD_TYPEDEF;
else
return FFI_OK;
/*@=usedef@*/
}
/* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
ffi_abi abi, unsigned int nargs,
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
/*@dependent@*/ ffi_type **atypes)
{
unsigned bytes = 0;
unsigned int i;
ffi_type **ptr;
FFI_ASSERT(cif != NULL);
FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
cif->abi = abi;
cif->arg_types = atypes;
cif->nargs = nargs;
cif->rtype = rtype;
cif->flags = 0;
/* Initialize the return type if necessary */
/*@-usedef@*/
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
return FFI_BAD_TYPEDEF;
/*@=usedef@*/
/* 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
/* Make space for the return structure pointer */
if (cif->rtype->type == FFI_TYPE_STRUCT
/* MSVC returns small structures in registers. But we have a different
workaround: pretend int32 or int64 return type, and converting to
structure afterwards. */
#ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif
)
bytes = STACK_ARG_SIZE(sizeof(void*));
#endif
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
/* Initialize any uninitialized aggregate type definitions */
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
/* Perform a sanity check on the argument type, do this
check after the initialization. */
FFI_ASSERT_VALID_TYPE(*ptr);
#if !defined __x86_64__ && !defined S390
#ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
&& cif->abi != FFI_V9))
bytes += sizeof(void*);
else
#endif
{
#ifndef _MSC_VER
/* Don't know if this is a libffi bug or not. At least on
Windows with MSVC, function call parameters are *not*
aligned in the same way as structure fields are, they are
only aligned in integer boundaries.
This doesn't do any harm for cdecl functions and closures,
since the caller cleans up the stack, but it is wrong for
stdcall functions where the callee cleans.
*/
/* Add any padding if necessary */
if (((*ptr)->alignment - 1) & bytes)
bytes = ALIGN(bytes, (*ptr)->alignment);
#endif
bytes += STACK_ARG_SIZE((*ptr)->size);
}
#endif
}
cif->bytes = bytes;
/* Perform machine dependent cif processing */
return ffi_prep_cif_machdep(cif);
}

View File

@ -1,228 +0,0 @@
; -----------------------------------------------------------------------
; sysv.S - Copyright (c) 1998 Red Hat, Inc.
;
; ARM 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 CYGNUS SOLUTIONS 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 <fficonfig.h>
;#include <ffi.h>
;#ifdef HAVE_MACHINE_ASM_H
;#include <machine/asm.h>
;#else
;#ifdef __USER_LABEL_PREFIX__
;#define CONCAT1(a, b) CONCAT2(a, b)
;#define CONCAT2(a, b) a ## b
;/* Use the right prefix for global labels. */
;#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
;#else
;#define CNAME(x) x
;#endif
;#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
;#endif
FFI_TYPE_VOID EQU 0
FFI_TYPE_INT EQU 1
FFI_TYPE_FLOAT EQU 2
FFI_TYPE_DOUBLE EQU 3
;FFI_TYPE_LONGDOUBLE EQU 4
FFI_TYPE_UINT8 EQU 5
FFI_TYPE_SINT8 EQU 6
FFI_TYPE_UINT16 EQU 7
FFI_TYPE_SINT16 EQU 8
FFI_TYPE_UINT32 EQU 9
FFI_TYPE_SINT32 EQU 10
FFI_TYPE_UINT64 EQU 11
FFI_TYPE_SINT64 EQU 12
FFI_TYPE_STRUCT EQU 13
FFI_TYPE_POINTER EQU 14
; WinCE always uses software floating point (I think)
__SOFTFP__ EQU {TRUE}
AREA |.text|, CODE, ARM ; .text
; a1: ffi_prep_args
; a2: &ecif
; a3: cif->bytes
; a4: fig->flags
; sp+0: ecif.rvalue
; sp+4: fn
; This assumes we are using gas.
;ENTRY(ffi_call_SYSV)
EXPORT |ffi_call_SYSV|
|ffi_call_SYSV| PROC
; Save registers
stmfd sp!, {a1-a4, fp, lr}
mov fp, sp
; Make room for all of the new args.
sub sp, fp, a3
; Place all of the ffi_prep_args in position
mov ip, a1
mov a1, sp
; a2 already set
; And call
mov lr, pc
mov pc, ip
; move first 4 parameters in registers
ldr a1, [sp, #0]
ldr a2, [sp, #4]
ldr a3, [sp, #8]
ldr a4, [sp, #12]
; and adjust stack
ldr ip, [fp, #8]
cmp ip, #16
movge ip, #16
add sp, sp, ip
; call function
mov lr, pc
ldr pc, [fp, #28]
; Remove the space we pushed for the args
mov sp, fp
; Load a3 with the pointer to storage for the return value
ldr a3, [sp, #24]
; Load a4 with the return type code
ldr a4, [sp, #12]
; If the return value pointer is NULL, assume no return value.
cmp a3, #0
beq call_epilogue
; return INT
cmp a4, #FFI_TYPE_INT
streq a1, [a3]
beq call_epilogue
; return FLOAT
cmp a4, #FFI_TYPE_FLOAT
[ __SOFTFP__ ;ifdef __SOFTFP__
streq a1, [a3]
| ;else
stfeqs f0, [a3]
] ;endif
beq call_epilogue
; return DOUBLE or LONGDOUBLE
cmp a4, #FFI_TYPE_DOUBLE
[ __SOFTFP__ ;ifdef __SOFTFP__
stmeqia a3, {a1, a2}
| ;else
stfeqd f0, [a3]
] ;endif
beq call_epilogue
; return SINT64 or UINT64
cmp a4, #FFI_TYPE_SINT64
stmeqia a3, {a1, a2}
call_epilogue
ldmfd sp!, {a1-a4, fp, pc}
;.ffi_call_SYSV_end:
;.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
ENDP
RESERVE_RETURN EQU 16
; This function is called by the trampoline
; It is NOT callable from C
; ip = pointer to struct ffi_closure
IMPORT |ffi_closure_SYSV_inner|
EXPORT |ffi_closure_SYSV|
|ffi_closure_SYSV| PROC
; Store the argument registers on the stack
stmfd sp!, {a1-a4}
; Push the return address onto the stack
stmfd sp!, {lr}
mov a1, ip ; first arg = address of ffi_closure
add a2, sp, #4 ; second arg = sp+4 (points to saved a1)
; Allocate space for a non-struct return value
sub sp, sp, #RESERVE_RETURN
mov a3, sp ; third arg = return value address
; static unsigned int
; ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
bl ffi_closure_SYSV_inner
; a1 now contains the return type code
; At this point the return value is on the stack
; Transfer it to the correct registers if necessary
; return INT
cmp a1, #FFI_TYPE_INT
ldreq a1, [sp]
beq closure_epilogue
; return FLOAT
cmp a1, #FFI_TYPE_FLOAT
[ __SOFTFP__ ;ifdef __SOFTFP__
ldreq a1, [sp]
| ;else
stfeqs f0, [sp]
] ;endif
beq closure_epilogue
; return DOUBLE or LONGDOUBLE
cmp a1, #FFI_TYPE_DOUBLE
[ __SOFTFP__ ;ifdef __SOFTFP__
ldmeqia sp, {a1, a2}
| ;else
stfeqd f0, [sp]
] ;endif
beq closure_epilogue
; return SINT64 or UINT64
cmp a1, #FFI_TYPE_SINT64
ldmeqia sp, {a1, a2}
closure_epilogue
add sp, sp, #RESERVE_RETURN ; remove return value buffer
ldmfd sp!, {ip} ; ip = pop return address
add sp, sp, #16 ; remove saved argument registers {a1-a4} from the stack
mov pc, ip ; return
ENDP ; ffi_closure_SYSV
END

View File

@ -14,7 +14,6 @@ the following #defines
MS_WIN64 - Code specific to the MS Win64 API MS_WIN64 - Code specific to the MS Win64 API
MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs)
MS_WINDOWS - Code specific to Windows, but all versions. MS_WINDOWS - Code specific to Windows, but all versions.
MS_WINCE - Code specific to Windows CE
Py_ENABLE_SHARED - Code if the Python core is built as a DLL. Py_ENABLE_SHARED - Code if the Python core is built as a DLL.
Also note that neither "_M_IX86" or "_MSC_VER" should be used for Also note that neither "_M_IX86" or "_MSC_VER" should be used for
@ -30,10 +29,6 @@ WIN32 is still required for the locale module.
*/ */
#ifdef _WIN32_WCE
#define MS_WINCE
#endif
/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ /* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */
#ifdef USE_DL_EXPORT #ifdef USE_DL_EXPORT
# define Py_BUILD_CORE # define Py_BUILD_CORE
@ -53,8 +48,6 @@ WIN32 is still required for the locale module.
#define _CRT_NONSTDC_NO_DEPRECATE 1 #define _CRT_NONSTDC_NO_DEPRECATE 1
#endif #endif
/* Windows CE does not have these */
#ifndef MS_WINCE
#define HAVE_IO_H #define HAVE_IO_H
#define HAVE_SYS_UTIME_H #define HAVE_SYS_UTIME_H
#define HAVE_TEMPNAM #define HAVE_TEMPNAM
@ -62,11 +55,8 @@ WIN32 is still required for the locale module.
#define HAVE_TMPNAM #define HAVE_TMPNAM
#define HAVE_CLOCK #define HAVE_CLOCK
#define HAVE_STRERROR #define HAVE_STRERROR
#endif
#ifdef HAVE_IO_H
#include <io.h> #include <io.h>
#endif
#define HAVE_HYPOT #define HAVE_HYPOT
#define HAVE_STRFTIME #define HAVE_STRFTIME
@ -86,17 +76,6 @@ WIN32 is still required for the locale module.
#define USE_SOCKET #define USE_SOCKET
#endif #endif
/* CE6 doesn't have strdup() but _strdup(). Assume the same for earlier versions. */
#if defined(MS_WINCE)
# include <stdlib.h>
# define strdup _strdup
#endif
#ifdef MS_WINCE
/* Windows CE does not support environment variables */
#define getenv(v) (NULL)
#define environ (NULL)
#endif
/* Compiler specific defines */ /* Compiler specific defines */
@ -448,14 +427,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* #define const */ /* #define const */
/* Define to 1 if you have the <conio.h> header file. */ /* Define to 1 if you have the <conio.h> header file. */
#ifndef MS_WINCE
#define HAVE_CONIO_H 1 #define HAVE_CONIO_H 1
#endif
/* Define to 1 if you have the <direct.h> header file. */ /* Define to 1 if you have the <direct.h> header file. */
#ifndef MS_WINCE
#define HAVE_DIRECT_H 1 #define HAVE_DIRECT_H 1
#endif
/* Define if you have dirent.h. */ /* Define if you have dirent.h. */
/* #define DIRENT 1 */ /* #define DIRENT 1 */
@ -528,9 +503,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* #define HAVE_ALTZONE */ /* #define HAVE_ALTZONE */
/* Define if you have the putenv function. */ /* Define if you have the putenv function. */
#ifndef MS_WINCE
#define HAVE_PUTENV #define HAVE_PUTENV
#endif
/* Define if your compiler supports function prototypes */ /* Define if your compiler supports function prototypes */
#define HAVE_PROTOTYPES #define HAVE_PROTOTYPES
@ -558,9 +531,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
#define HAVE_DYNAMIC_LOADING #define HAVE_DYNAMIC_LOADING
/* Define if you have ftime. */ /* Define if you have ftime. */
#ifndef MS_WINCE
#define HAVE_FTIME #define HAVE_FTIME
#endif
/* Define if you have getpeername. */ /* Define if you have getpeername. */
#define HAVE_GETPEERNAME #define HAVE_GETPEERNAME
@ -569,9 +540,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* #undef HAVE_GETPGRP */ /* #undef HAVE_GETPGRP */
/* Define if you have getpid. */ /* Define if you have getpid. */
#ifndef MS_WINCE
#define HAVE_GETPID #define HAVE_GETPID
#endif
/* Define if you have gettimeofday. */ /* Define if you have gettimeofday. */
/* #undef HAVE_GETTIMEOFDAY */ /* #undef HAVE_GETTIMEOFDAY */
@ -633,14 +602,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
#endif #endif
/* Define to 1 if you have the `wcscoll' function. */ /* Define to 1 if you have the `wcscoll' function. */
#ifndef MS_WINCE
#define HAVE_WCSCOLL 1 #define HAVE_WCSCOLL 1
#endif
/* Define to 1 if you have the `wcsxfrm' function. */ /* Define to 1 if you have the `wcsxfrm' function. */
#ifndef MS_WINCE
#define HAVE_WCSXFRM 1 #define HAVE_WCSXFRM 1
#endif
/* Define if the zlib library has inflateCopy */ /* Define if the zlib library has inflateCopy */
#define HAVE_ZLIB_COPY 1 #define HAVE_ZLIB_COPY 1
@ -649,24 +614,16 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* #undef HAVE_DLFCN_H */ /* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <errno.h> header file. */ /* Define to 1 if you have the <errno.h> header file. */
#ifndef MS_WINCE
#define HAVE_ERRNO_H 1 #define HAVE_ERRNO_H 1
#endif
/* Define if you have the <fcntl.h> header file. */ /* Define if you have the <fcntl.h> header file. */
#ifndef MS_WINCE
#define HAVE_FCNTL_H 1 #define HAVE_FCNTL_H 1
#endif
/* Define to 1 if you have the <process.h> header file. */ /* Define to 1 if you have the <process.h> header file. */
#ifndef MS_WINCE
#define HAVE_PROCESS_H 1 #define HAVE_PROCESS_H 1
#endif
/* Define to 1 if you have the <signal.h> header file. */ /* Define to 1 if you have the <signal.h> header file. */
#ifndef MS_WINCE
#define HAVE_SIGNAL_H 1 #define HAVE_SIGNAL_H 1
#endif
/* Define if you have the <stdarg.h> prototypes. */ /* Define if you have the <stdarg.h> prototypes. */
#define HAVE_STDARG_PROTOTYPES #define HAVE_STDARG_PROTOTYPES
@ -684,9 +641,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* #define HAVE_SYS_SELECT_H 1 */ /* #define HAVE_SYS_SELECT_H 1 */
/* Define to 1 if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/stat.h> header file. */
#ifndef MS_WINCE
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1
#endif
/* Define if you have the <sys/time.h> header file. */ /* Define if you have the <sys/time.h> header file. */
/* #define HAVE_SYS_TIME_H 1 */ /* #define HAVE_SYS_TIME_H 1 */
@ -695,9 +650,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* #define HAVE_SYS_TIMES_H 1 */ /* #define HAVE_SYS_TIMES_H 1 */
/* Define to 1 if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
#ifndef MS_WINCE
#define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_TYPES_H 1
#endif
/* Define if you have the <sys/un.h> header file. */ /* Define if you have the <sys/un.h> header file. */
/* #define HAVE_SYS_UN_H 1 */ /* #define HAVE_SYS_UN_H 1 */

View File

@ -2000,7 +2000,7 @@ sys_update_path(int argc, wchar_t **argv)
#endif #endif
#if defined(HAVE_REALPATH) #if defined(HAVE_REALPATH)
wchar_t fullpath[MAXPATHLEN]; wchar_t fullpath[MAXPATHLEN];
#elif defined(MS_WINDOWS) && !defined(MS_WINCE) #elif defined(MS_WINDOWS)
wchar_t fullpath[MAX_PATH]; wchar_t fullpath[MAX_PATH];
#endif #endif
@ -2039,10 +2039,8 @@ sys_update_path(int argc, wchar_t **argv)
#if SEP == '\\' /* Special case for MS filename syntax */ #if SEP == '\\' /* Special case for MS filename syntax */
if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) { if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
wchar_t *q; wchar_t *q;
#if defined(MS_WINDOWS) && !defined(MS_WINCE) #if defined(MS_WINDOWS)
/* This code here replaces the first element in argv with the full /* Replace the first element in argv with the full path. */
path that it represents. Under CE, there are no relative paths so
the argument must be the full path anyway. */
wchar_t *ptemp; wchar_t *ptemp;
if (GetFullPathNameW(argv0, if (GetFullPathNameW(argv0,
Py_ARRAY_LENGTH(fullpath), Py_ARRAY_LENGTH(fullpath),

View File

@ -161,11 +161,7 @@ typedef struct {
/* thunker to call adapt between the function type used by the system's /* thunker to call adapt between the function type used by the system's
thread start function and the internally used one. */ thread start function and the internally used one. */
#if defined(MS_WINCE)
static DWORD WINAPI
#else
static unsigned __stdcall static unsigned __stdcall
#endif
bootstrap(void *call) bootstrap(void *call)
{ {
callobj *obj = (callobj*)call; callobj *obj = (callobj*)call;
@ -193,32 +189,18 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
return -1; return -1;
obj->func = func; obj->func = func;
obj->arg = arg; obj->arg = arg;
#if defined(MS_WINCE)
hThread = CreateThread(NULL,
Py_SAFE_DOWNCAST(_pythread_stacksize, Py_ssize_t, SIZE_T),
bootstrap, obj, 0, &threadID);
#else
hThread = (HANDLE)_beginthreadex(0, hThread = (HANDLE)_beginthreadex(0,
Py_SAFE_DOWNCAST(_pythread_stacksize, Py_SAFE_DOWNCAST(_pythread_stacksize,
Py_ssize_t, unsigned int), Py_ssize_t, unsigned int),
bootstrap, obj, bootstrap, obj,
0, &threadID); 0, &threadID);
#endif
if (hThread == 0) { if (hThread == 0) {
#if defined(MS_WINCE)
/* Save error in variable, to prevent PyThread_get_thread_ident
from clobbering it. */
unsigned e = GetLastError();
dprintf(("%ld: PyThread_start_new_thread failed, win32 error code %u\n",
PyThread_get_thread_ident(), e));
#else
/* I've seen errno == EAGAIN here, which means "there are /* I've seen errno == EAGAIN here, which means "there are
* too many threads". * too many threads".
*/ */
int e = errno; int e = errno;
dprintf(("%ld: PyThread_start_new_thread failed, errno %d\n", dprintf(("%ld: PyThread_start_new_thread failed, errno %d\n",
PyThread_get_thread_ident(), e)); PyThread_get_thread_ident(), e));
#endif
threadID = (unsigned)-1; threadID = (unsigned)-1;
HeapFree(GetProcessHeap(), 0, obj); HeapFree(GetProcessHeap(), 0, obj);
} }
@ -249,11 +231,7 @@ PyThread_exit_thread(void)
dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident())); dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
if (!initialized) if (!initialized)
exit(0); exit(0);
#if defined(MS_WINCE)
ExitThread(0);
#else
_endthreadex(0); _endthreadex(0);
#endif
} }
/* /*

View File

@ -124,9 +124,7 @@ def main():
# default the exclude list for each platform # default the exclude list for each platform
if win: exclude = exclude + [ if win: exclude = exclude + [
'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', 'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', ]
'ce',
]
fail_import = exclude[:] fail_import = exclude[:]