[pypy-commit] pypy cffi-1.0: Import cffi 1.0.0 (revision 8bb4a702b17d)

arigo noreply at buildbot.pypy.org
Sat May 9 11:13:21 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r77241:a365f60463e9
Date: 2015-05-09 08:59 +0000
http://bitbucket.org/pypy/pypy/changeset/a365f60463e9/

Log:	Import cffi 1.0.0 (revision 8bb4a702b17d)

diff too long, truncating to 2000 out of 7137 lines

diff --git a/lib_pypy/_cffi1/__init__.py b/lib_pypy/_cffi1/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/__init__.py
@@ -0,0 +1,1 @@
+from .recompiler import make_c_source, recompile
diff --git a/lib_pypy/_cffi1/cffi_opcode.py b/lib_pypy/_cffi1/cffi_opcode.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/cffi_opcode.py
@@ -0,0 +1,144 @@
+
+class CffiOp(object):
+    def __init__(self, op, arg):
+        self.op = op
+        self.arg = arg
+    def as_c_expr(self):
+        if self.op is None:
+            assert isinstance(self.arg, str)
+            return '(_cffi_opcode_t)(%s)' % (self.arg,)
+        classname = CLASS_NAME[self.op]
+        return '_CFFI_OP(_CFFI_OP_%s, %d)' % (classname, self.arg)
+    def __str__(self):
+        classname = CLASS_NAME.get(self.op, self.op)
+        return '(%s %s)' % (classname, self.arg)
+
+OP_PRIMITIVE       = 1
+OP_POINTER         = 3
+OP_ARRAY           = 5
+OP_OPEN_ARRAY      = 7
+OP_STRUCT_UNION    = 9
+OP_ENUM            = 11
+OP_FUNCTION        = 13
+OP_FUNCTION_END    = 15
+OP_NOOP            = 17
+OP_BITFIELD        = 19
+OP_TYPENAME        = 21
+OP_CPYTHON_BLTN_V  = 23   # varargs
+OP_CPYTHON_BLTN_N  = 25   # noargs
+OP_CPYTHON_BLTN_O  = 27   # O  (i.e. a single arg)
+OP_CONSTANT        = 29
+OP_CONSTANT_INT    = 31
+OP_GLOBAL_VAR      = 33
+
+PRIM_VOID          = 0
+PRIM_BOOL          = 1
+PRIM_CHAR          = 2
+PRIM_SCHAR         = 3
+PRIM_UCHAR         = 4
+PRIM_SHORT         = 5
+PRIM_USHORT        = 6
+PRIM_INT           = 7
+PRIM_UINT          = 8
+PRIM_LONG          = 9
+PRIM_ULONG         = 10
+PRIM_LONGLONG      = 11
+PRIM_ULONGLONG     = 12
+PRIM_FLOAT         = 13
+PRIM_DOUBLE        = 14
+PRIM_LONGDOUBLE    = 15
+
+PRIM_WCHAR         = 16
+PRIM_INT8          = 17
+PRIM_UINT8         = 18
+PRIM_INT16         = 19
+PRIM_UINT16        = 20
+PRIM_INT32         = 21
+PRIM_UINT32        = 22
+PRIM_INT64         = 23
+PRIM_UINT64        = 24
+PRIM_INTPTR        = 25
+PRIM_UINTPTR       = 26
+PRIM_PTRDIFF       = 27
+PRIM_SIZE          = 28
+PRIM_SSIZE         = 29
+PRIM_INT_LEAST8    = 30
+PRIM_UINT_LEAST8   = 31
+PRIM_INT_LEAST16   = 32
+PRIM_UINT_LEAST16  = 33
+PRIM_INT_LEAST32   = 34
+PRIM_UINT_LEAST32  = 35
+PRIM_INT_LEAST64   = 36
+PRIM_UINT_LEAST64  = 37
+PRIM_INT_FAST8     = 38
+PRIM_UINT_FAST8    = 39
+PRIM_INT_FAST16    = 40
+PRIM_UINT_FAST16   = 41
+PRIM_INT_FAST32    = 42
+PRIM_UINT_FAST32   = 43
+PRIM_INT_FAST64    = 44
+PRIM_UINT_FAST64   = 45
+PRIM_INTMAX        = 46
+PRIM_UINTMAX       = 47
+
+_NUM_PRIM          = 48
+
+PRIMITIVE_TO_INDEX = {
+    'char':               PRIM_CHAR,
+    'short':              PRIM_SHORT,
+    'int':                PRIM_INT,
+    'long':               PRIM_LONG,
+    'long long':          PRIM_LONGLONG,
+    'signed char':        PRIM_SCHAR,
+    'unsigned char':      PRIM_UCHAR,
+    'unsigned short':     PRIM_USHORT,
+    'unsigned int':       PRIM_UINT,
+    'unsigned long':      PRIM_ULONG,
+    'unsigned long long': PRIM_ULONGLONG,
+    'float':              PRIM_FLOAT,
+    'double':             PRIM_DOUBLE,
+    'long double':        PRIM_LONGDOUBLE,
+    '_Bool':              PRIM_BOOL,
+    'wchar_t':            PRIM_WCHAR,
+    'int8_t':             PRIM_INT8,
+    'uint8_t':            PRIM_UINT8,
+    'int16_t':            PRIM_INT16,
+    'uint16_t':           PRIM_UINT16,
+    'int32_t':            PRIM_INT32,
+    'uint32_t':           PRIM_UINT32,
+    'int64_t':            PRIM_INT64,
+    'uint64_t':           PRIM_UINT64,
+    'intptr_t':           PRIM_INTPTR,
+    'uintptr_t':          PRIM_UINTPTR,
+    'ptrdiff_t':          PRIM_PTRDIFF,
+    'size_t':             PRIM_SIZE,
+    'ssize_t':            PRIM_SSIZE,
+    'int_least8_t':       PRIM_INT_LEAST8,
+    'uint_least8_t':      PRIM_UINT_LEAST8,
+    'int_least16_t':      PRIM_INT_LEAST16,
+    'uint_least16_t':     PRIM_UINT_LEAST16,
+    'int_least32_t':      PRIM_INT_LEAST32,
+    'uint_least32_t':     PRIM_UINT_LEAST32,
+    'int_least64_t':      PRIM_INT_LEAST64,
+    'uint_least64_t':     PRIM_UINT_LEAST64,
+    'int_fast8_t':        PRIM_INT_FAST8,
+    'uint_fast8_t':       PRIM_UINT_FAST8,
+    'int_fast16_t':       PRIM_INT_FAST16,
+    'uint_fast16_t':      PRIM_UINT_FAST16,
+    'int_fast32_t':       PRIM_INT_FAST32,
+    'uint_fast32_t':      PRIM_UINT_FAST32,
+    'int_fast64_t':       PRIM_INT_FAST64,
+    'uint_fast64_t':      PRIM_UINT_FAST64,
+    'intmax_t':           PRIM_INTMAX,
+    'uintmax_t':          PRIM_UINTMAX,
+    }
+
+F_UNION         = 0x01
+F_CHECK_FIELDS  = 0x02
+F_PACKED        = 0x04
+F_EXTERNAL      = 0x08
+
+CLASS_NAME = {}
+for _name, _value in list(globals().items()):
+    if _name.startswith('OP_') and isinstance(_value, int):
+        CLASS_NAME[_value] = _name[3:]
diff --git a/lib_pypy/_cffi1/recompiler.py b/lib_pypy/_cffi1/recompiler.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/recompiler.py
@@ -0,0 +1,906 @@
+import os, sys, io
+from cffi import ffiplatform, model
+from .cffi_opcode import *
+
+
+class Recompiler:
+
+    def __init__(self, ffi, module_name):
+        self.ffi = ffi
+        self.module_name = module_name
+
+    def collect_type_table(self):
+        self._typesdict = {}
+        self._generate("collecttype")
+        #
+        all_decls = sorted(self._typesdict, key=str)
+        #
+        # prepare all FUNCTION bytecode sequences first
+        self.cffi_types = []
+        for tp in all_decls:
+            if tp.is_raw_function:
+                assert self._typesdict[tp] is None
+                self._typesdict[tp] = len(self.cffi_types)
+                self.cffi_types.append(tp)     # placeholder
+                for tp1 in tp.args:
+                    assert isinstance(tp1, (model.VoidType,
+                                            model.PrimitiveType,
+                                            model.PointerType,
+                                            model.StructOrUnionOrEnum,
+                                            model.FunctionPtrType))
+                    if self._typesdict[tp1] is None:
+                        self._typesdict[tp1] = len(self.cffi_types)
+                    self.cffi_types.append(tp1)   # placeholder
+                self.cffi_types.append('END')     # placeholder
+        #
+        # prepare all OTHER bytecode sequences
+        for tp in all_decls:
+            if not tp.is_raw_function and self._typesdict[tp] is None:
+                self._typesdict[tp] = len(self.cffi_types)
+                self.cffi_types.append(tp)        # placeholder
+                if tp.is_array_type and tp.length is not None:
+                    self.cffi_types.append('LEN') # placeholder
+        assert None not in self._typesdict.values()
+        #
+        # collect all structs and unions and enums
+        self._struct_unions = {}
+        self._enums = {}
+        for tp in all_decls:
+            if isinstance(tp, model.StructOrUnion):
+                self._struct_unions[tp] = None
+            elif isinstance(tp, model.EnumType):
+                self._enums[tp] = None
+        for i, tp in enumerate(sorted(self._struct_unions,
+                                      key=lambda tp: tp.name)):
+            self._struct_unions[tp] = i
+        for i, tp in enumerate(sorted(self._enums,
+                                      key=lambda tp: tp.name)):
+            self._enums[tp] = i
+        #
+        # emit all bytecode sequences now
+        for tp in all_decls:
+            method = getattr(self, '_emit_bytecode_' + tp.__class__.__name__)
+            method(tp, self._typesdict[tp])
+        #
+        # consistency check
+        for op in self.cffi_types:
+            assert isinstance(op, CffiOp)
+
+    def _do_collect_type(self, tp):
+        if not isinstance(tp, model.BaseTypeByIdentity):
+            if isinstance(tp, tuple):
+                for x in tp:
+                    self._do_collect_type(x)
+            return
+        if tp not in self._typesdict:
+            self._typesdict[tp] = None
+            if isinstance(tp, model.FunctionPtrType):
+                self._do_collect_type(tp.as_raw_function())
+            elif isinstance(tp, model.StructOrUnion):
+                if tp.fldtypes is not None and (
+                        tp not in self.ffi._parser._included_declarations):
+                    for name1, tp1, _ in tp.enumfields():
+                        self._do_collect_type(self._field_type(tp, name1, tp1))
+            else:
+                for _, x in tp._get_items():
+                    self._do_collect_type(x)
+
+    def _get_declarations(self):
+        return sorted(self.ffi._parser._declarations.items())
+
+    def _generate(self, step_name):
+        for name, tp in self._get_declarations():
+            kind, realname = name.split(' ', 1)
+            try:
+                method = getattr(self, '_generate_cpy_%s_%s' % (kind,
+                                                                step_name))
+            except AttributeError:
+                raise ffiplatform.VerificationError(
+                    "not implemented in recompile(): %r" % name)
+            try:
+                method(tp, realname)
+            except Exception as e:
+                model.attach_exception_info(e, name)
+                raise
+
+    # ----------
+
+    def _prnt(self, what=''):
+        self._f.write(what + '\n')
+
+    def _gettypenum(self, type):
+        # a KeyError here is a bug.  please report it! :-)
+        return self._typesdict[type]
+
+    def _rel_readlines(self, filename):
+        g = open(os.path.join(os.path.dirname(__file__), filename), 'r')
+        lines = g.readlines()
+        g.close()
+        return lines
+
+    def write_source_to_f(self, f, preamble):
+        self._f = f
+        prnt = self._prnt
+        #
+        # first the '#include' (actually done by inlining the file's content)
+        lines = self._rel_readlines('_cffi_include.h')
+        i = lines.index('#include "parse_c_type.h"\n')
+        lines[i:i+1] = self._rel_readlines('parse_c_type.h')
+        prnt(''.join(lines))
+        #
+        # then paste the C source given by the user, verbatim.
+        prnt('/************************************************************/')
+        prnt()
+        prnt(preamble)
+        prnt()
+        prnt('/************************************************************/')
+        prnt()
+        #
+        # the declaration of '_cffi_types'
+        prnt('static void *_cffi_types[] = {')
+        self.cffi_types = tuple(self.cffi_types)    # don't change any more
+        typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()])
+        for i, op in enumerate(self.cffi_types):
+            comment = ''
+            if i in typeindex2type:
+                comment = ' // ' + typeindex2type[i]._get_c_name()
+            prnt('/* %2d */ %s,%s' % (i, op.as_c_expr(), comment))
+        if not self.cffi_types:
+            prnt('  0')
+        prnt('};')
+        prnt()
+        #
+        # call generate_cpy_xxx_decl(), for every xxx found from
+        # ffi._parser._declarations.  This generates all the functions.
+        self._seen_constants = set()
+        self._generate("decl")
+        #
+        # the declaration of '_cffi_globals' and '_cffi_typenames'
+        ALL_STEPS = ["global", "field", "struct_union", "enum", "typename"]
+        nums = {}
+        self._lsts = {}
+        for step_name in ALL_STEPS:
+            self._lsts[step_name] = []
+        self._seen_struct_unions = set()
+        self._generate("ctx")
+        self._add_missing_struct_unions()
+        for step_name in ALL_STEPS:
+            lst = self._lsts[step_name]
+            nums[step_name] = len(lst)
+            if nums[step_name] > 0:
+                lst.sort()  # sort by name, which is at the start of each line
+                prnt('static const struct _cffi_%s_s _cffi_%ss[] = {' % (
+                    step_name, step_name))
+                if step_name == 'field':
+                    self._fix_final_field_list(lst)
+                for line in lst:
+                    prnt(line)
+                if all(line.startswith('#') for line in lst):
+                    prnt('  { 0 }')
+                prnt('};')
+                prnt()
+        #
+        # check for a possible internal inconsistency: _cffi_struct_unions
+        # should have been generated with exactly self._struct_unions
+        lst = self._lsts["struct_union"]
+        for tp, i in self._struct_unions.items():
+            assert i < len(lst)
+            assert lst[i].startswith('  { "%s"' % tp.name)
+        assert len(lst) == len(self._struct_unions)
+        # same with enums
+        lst = self._lsts["enum"]
+        for tp, i in self._enums.items():
+            assert i < len(lst)
+            assert lst[i].startswith('  { "%s"' % tp.name)
+        assert len(lst) == len(self._enums)
+        #
+        # the declaration of '_cffi_includes'
+        if self.ffi._included_ffis:
+            prnt('static const char * const _cffi_includes[] = {')
+            for ffi_to_include in self.ffi._included_ffis:
+                if not hasattr(ffi_to_include, '_recompiler_module_name'):
+                    raise ffiplatform.VerificationError(
+                        "this ffi includes %r, but the latter has not been "
+                        "turned into a C module" % (ffi_to_include,))
+                prnt('  "%s",' % (ffi_to_include._recompiler_module_name,))
+            prnt('  NULL')
+            prnt('};')
+            prnt()
+        #
+        # the declaration of '_cffi_type_context'
+        prnt('static const struct _cffi_type_context_s _cffi_type_context = {')
+        prnt('  _cffi_types,')
+        for step_name in ALL_STEPS:
+            if nums[step_name] > 0:
+                prnt('  _cffi_%ss,' % step_name)
+            else:
+                prnt('  NULL,  /* no %ss */' % step_name)
+        for step_name in ALL_STEPS:
+            if step_name != "field":
+                prnt('  %d,  /* num_%ss */' % (nums[step_name], step_name))
+        if self.ffi._included_ffis:
+            prnt('  _cffi_includes,')
+        else:
+            prnt('  NULL,  /* no includes */')
+        prnt('  %d,  /* num_types */' % (len(self.cffi_types),))
+        prnt('  0,  /* flags */')
+        prnt('};')
+        prnt()
+        #
+        # the init function, loading _cffi_backend and calling a method there
+        base_module_name = self.module_name.split('.')[-1]
+        prnt('#ifdef PYPY_VERSION')
+        prnt('PyMODINIT_FUNC')
+        prnt('_cffi_pypyinit_%s(const void *p[])' % (base_module_name,))
+        prnt('{')
+        prnt('    p[0] = (const void *)0x10000f0;')
+        prnt('    p[1] = &_cffi_type_context;')
+        prnt('}')
+        prnt('#elif PY_MAJOR_VERSION >= 3')
+        prnt('PyMODINIT_FUNC')
+        prnt('PyInit_%s(void)' % (base_module_name,))
+        prnt('{')
+        prnt('  if (_cffi_init() < 0)')
+        prnt('    return NULL;')
+        prnt('  return _cffi_init_module("%s", &_cffi_type_context);' % (
+            self.module_name,))
+        prnt('}')
+        prnt('#else')
+        prnt('PyMODINIT_FUNC')
+        prnt('init%s(void)' % (base_module_name,))
+        prnt('{')
+        prnt('  if (_cffi_init() < 0)')
+        prnt('    return;')
+        prnt('  _cffi_init_module("%s", &_cffi_type_context);' % (
+            self.module_name,))
+        prnt('}')
+        prnt('#endif')
+        self.ffi._recompiler_module_name = self.module_name
+
+    # ----------
+
+    def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode):
+        extraarg = ''
+        if isinstance(tp, model.PrimitiveType):
+            if tp.is_integer_type() and tp.name != '_Bool':
+                converter = '_cffi_to_c_int'
+                extraarg = ', %s' % tp.name
+            else:
+                converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''),
+                                                   tp.name.replace(' ', '_'))
+            errvalue = '-1'
+        #
+        elif isinstance(tp, model.PointerType):
+            self._convert_funcarg_to_c_ptr_or_array(tp, fromvar,
+                                                    tovar, errcode)
+            return
+        #
+        elif isinstance(tp, (model.StructOrUnion, model.EnumType)):
+            # a struct (not a struct pointer) as a function argument
+            self._prnt('  if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)'
+                      % (tovar, self._gettypenum(tp), fromvar))
+            self._prnt('    %s;' % errcode)
+            return
+        #
+        elif isinstance(tp, model.FunctionPtrType):
+            converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('')
+            extraarg = ', _cffi_type(%d)' % self._gettypenum(tp)
+            errvalue = 'NULL'
+        #
+        else:
+            raise NotImplementedError(tp)
+        #
+        self._prnt('  %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg))
+        self._prnt('  if (%s == (%s)%s && PyErr_Occurred())' % (
+            tovar, tp.get_c_name(''), errvalue))
+        self._prnt('    %s;' % errcode)
+
+    def _extra_local_variables(self, tp, localvars):
+        if isinstance(tp, model.PointerType):
+            localvars.add('Py_ssize_t datasize')
+
+    def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode):
+        self._prnt('  datasize = _cffi_prepare_pointer_call_argument(')
+        self._prnt('      _cffi_type(%d), %s, (char **)&%s);' % (
+            self._gettypenum(tp), fromvar, tovar))
+        self._prnt('  if (datasize != 0) {')
+        self._prnt('    if (datasize < 0)')
+        self._prnt('      %s;' % errcode)
+        self._prnt('    %s = alloca((size_t)datasize);' % (tovar,))
+        self._prnt('    memset((void *)%s, 0, (size_t)datasize);' % (tovar,))
+        self._prnt('    if (_cffi_convert_array_from_object('
+                   '(char *)%s, _cffi_type(%d), %s) < 0)' % (
+            tovar, self._gettypenum(tp), fromvar))
+        self._prnt('      %s;' % errcode)
+        self._prnt('  }')
+
+    def _convert_expr_from_c(self, tp, var, context):
+        if isinstance(tp, model.PrimitiveType):
+            if tp.is_integer_type():
+                return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
+            elif tp.name != 'long double':
+                return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
+            else:
+                return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % (
+                    var, self._gettypenum(tp))
+        elif isinstance(tp, (model.PointerType, model.FunctionPtrType)):
+            return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
+                var, self._gettypenum(tp))
+        elif isinstance(tp, model.ArrayType):
+            return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
+                var, self._gettypenum(model.PointerType(tp.item)))
+        elif isinstance(tp, model.StructType):
+            if tp.fldnames is None:
+                raise TypeError("'%s' is used as %s, but is opaque" % (
+                    tp._get_c_name(), context))
+            return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % (
+                var, self._gettypenum(tp))
+        elif isinstance(tp, model.EnumType):
+            return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % (
+                var, self._gettypenum(tp))
+        else:
+            raise NotImplementedError(tp)
+
+    # ----------
+    # typedefs
+
+    def _generate_cpy_typedef_collecttype(self, tp, name):
+        self._do_collect_type(tp)
+
+    def _generate_cpy_typedef_decl(self, tp, name):
+        pass
+
+    def _typedef_ctx(self, tp, name):
+        type_index = self._typesdict[tp]
+        self._lsts["typename"].append(
+            '  { "%s", %d },' % (name, type_index))
+
+    def _generate_cpy_typedef_ctx(self, tp, name):
+        self._typedef_ctx(tp, name)
+        if getattr(tp, "origin", None) == "unknown_type":
+            self._struct_ctx(tp, tp.name, approxname=None)
+        elif isinstance(tp, model.NamedPointerType):
+            self._struct_ctx(tp.totype, tp.totype.name, approxname=None)
+
+    # ----------
+    # function declarations
+
+    def _generate_cpy_function_collecttype(self, tp, name):
+        self._do_collect_type(tp.as_raw_function())
+        if tp.ellipsis:
+            self._do_collect_type(tp)
+
+    def _generate_cpy_function_decl(self, tp, name):
+        assert isinstance(tp, model.FunctionPtrType)
+        if tp.ellipsis:
+            # cannot support vararg functions better than this: check for its
+            # exact type (including the fixed arguments), and build it as a
+            # constant function pointer (no CPython wrapper)
+            self._generate_cpy_constant_decl(tp, name)
+            return
+        prnt = self._prnt
+        numargs = len(tp.args)
+        if numargs == 0:
+            argname = 'noarg'
+        elif numargs == 1:
+            argname = 'arg0'
+        else:
+            argname = 'args'
+        prnt('#ifndef PYPY_VERSION')        # ------------------------------
+        prnt('static PyObject *')
+        prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname))
+        prnt('{')
+        #
+        context = 'argument of %s' % name
+        arguments = []
+        for i, type in enumerate(tp.args):
+            arg = type.get_c_name(' x%d' % i, context)
+            arguments.append(arg)
+            prnt('  %s;' % arg)
+        #
+        localvars = set()
+        for type in tp.args:
+            self._extra_local_variables(type, localvars)
+        for decl in localvars:
+            prnt('  %s;' % (decl,))
+        #
+        if not isinstance(tp.result, model.VoidType):
+            result_code = 'result = '
+            context = 'result of %s' % name
+            result_decl = '  %s;' % tp.result.get_c_name(' result', context)
+            prnt(result_decl)
+        else:
+            result_decl = None
+            result_code = ''
+        #
+        if len(tp.args) > 1:
+            rng = range(len(tp.args))
+            for i in rng:
+                prnt('  PyObject *arg%d;' % i)
+            prnt()
+            prnt('  if (!PyArg_ParseTuple(args, "%s:%s", %s))' % (
+                'O' * numargs, name, ', '.join(['&arg%d' % i for i in rng])))
+            prnt('    return NULL;')
+        prnt()
+        #
+        for i, type in enumerate(tp.args):
+            self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i,
+                                       'return NULL')
+            prnt()
+        #
+        prnt('  Py_BEGIN_ALLOW_THREADS')
+        prnt('  _cffi_restore_errno();')
+        call_arguments = ['x%d' % i for i in range(len(tp.args))]
+        call_arguments = ', '.join(call_arguments)
+        call_code = '  { %s%s(%s); }' % (result_code, name, call_arguments)
+        prnt(call_code)
+        prnt('  _cffi_save_errno();')
+        prnt('  Py_END_ALLOW_THREADS')
+        prnt()
+        #
+        prnt('  (void)self; /* unused */')
+        if numargs == 0:
+            prnt('  (void)noarg; /* unused */')
+        if result_code:
+            prnt('  return %s;' %
+                 self._convert_expr_from_c(tp.result, 'result', 'result type'))
+        else:
+            prnt('  Py_INCREF(Py_None);')
+            prnt('  return Py_None;')
+        prnt('}')
+        prnt('#else')        # ------------------------------
+        repr_arguments = ', '.join(arguments)
+        repr_arguments = repr_arguments or 'void'
+        name_and_arguments = '_cffi_f_%s(%s)' % (name, repr_arguments)
+        prnt('static %s' % (tp.result.get_c_name(name_and_arguments),))
+        prnt('{')
+        if result_decl:
+            prnt(result_decl)
+        prnt(call_code)
+        if result_decl:
+            prnt('  return result;')
+        prnt('}')
+        prnt('#endif')        # ------------------------------
+        prnt()
+
+    def _generate_cpy_function_ctx(self, tp, name):
+        if tp.ellipsis:
+            self._generate_cpy_constant_ctx(tp, name)
+            return
+        type_index = self._typesdict[tp.as_raw_function()]
+        numargs = len(tp.args)
+        if numargs == 0:
+            meth_kind = 'N'   # 'METH_NOARGS'
+        elif numargs == 1:
+            meth_kind = 'O'   # 'METH_O'
+        else:
+            meth_kind = 'V'   # 'METH_VARARGS'
+        self._lsts["global"].append(
+            '  { "%s", _cffi_f_%s, _CFFI_OP(_CFFI_OP_CPYTHON_BLTN_%s, %d), 0 },'
+            % (name, name, meth_kind, type_index))
+
+    # ----------
+    # named structs or unions
+
+    def _field_type(self, tp_struct, field_name, tp_field):
+        if isinstance(tp_field, model.ArrayType) and tp_field.length == '...':
+            ptr_struct_name = tp_struct.get_c_name('*')
+            actual_length = '_cffi_array_len(((%s)0)->%s)' % (
+                ptr_struct_name, field_name)
+            tp_field = tp_field.resolve_length(actual_length)
+        return tp_field
+
+    def _struct_collecttype(self, tp):
+        self._do_collect_type(tp)
+
+    def _struct_decl(self, tp, cname, approxname):
+        if tp.fldtypes is None:
+            return
+        prnt = self._prnt
+        checkfuncname = '_cffi_checkfld_%s' % (approxname,)
+        prnt('_CFFI_UNUSED_FN')
+        prnt('static void %s(%s *p)' % (checkfuncname, cname))
+        prnt('{')
+        prnt('  /* only to generate compile-time warnings or errors */')
+        prnt('  (void)p;')
+        for fname, ftype, fbitsize in tp.enumfields():
+            if (isinstance(ftype, model.PrimitiveType)
+                and ftype.is_integer_type()) or fbitsize >= 0:
+                # accept all integers, but complain on float or double
+                prnt('  (void)((p->%s) << 1);' % fname)
+            else:
+                # only accept exactly the type declared.
+                try:
+                    prnt('  { %s = &p->%s; (void)tmp; }' % (
+                        ftype.get_c_name('*tmp', 'field %r'%fname), fname))
+                except ffiplatform.VerificationError as e:
+                    prnt('  /* %s */' % str(e))   # cannot verify it, ignore
+        prnt('}')
+        prnt('struct _cffi_align_%s { char x; %s y; };' % (approxname, cname))
+        prnt()
+
+    def _struct_ctx(self, tp, cname, approxname):
+        type_index = self._typesdict[tp]
+        reason_for_not_expanding = None
+        flags = []
+        if isinstance(tp, model.UnionType):
+            flags.append("_CFFI_F_UNION")
+        if tp not in self.ffi._parser._included_declarations:
+            if tp.fldtypes is None:
+                reason_for_not_expanding = "opaque"
+            elif tp.partial or tp.has_anonymous_struct_fields():
+                pass    # field layout obtained silently from the C compiler
+            else:
+                flags.append("_CFFI_F_CHECK_FIELDS")
+            if tp.packed:
+                flags.append("_CFFI_F_PACKED")
+        else:
+            flags.append("_CFFI_F_EXTERNAL")
+            reason_for_not_expanding = "external"
+        flags = '|'.join(flags) or '0'
+        if reason_for_not_expanding is None:
+            c_field = [approxname]
+            enumfields = list(tp.enumfields())
+            for fldname, fldtype, fbitsize in enumfields:
+                fldtype = self._field_type(tp, fldname, fldtype)
+                spaces = " " * len(fldname)
+                # cname is None for _add_missing_struct_unions() only
+                op = '_CFFI_OP_NOOP'
+                if fbitsize >= 0:
+                    op = '_CFFI_OP_BITFIELD'
+                    size = '%d /* bits */' % fbitsize
+                elif cname is None or (
+                        isinstance(fldtype, model.ArrayType) and
+                        fldtype.length is None):
+                    size = '(size_t)-1'
+                else:
+                    size = 'sizeof(((%s)0)->%s)' % (tp.get_c_name('*'), fldname)
+                if cname is None or fbitsize >= 0:
+                    offset = '(size_t)-1'
+                else:
+                    offset = 'offsetof(%s, %s)' % (tp.get_c_name(''), fldname)
+                c_field.append(
+                    '  { "%s", %s,\n' % (fldname, offset) +
+                    '     %s   %s,\n' % (spaces, size) +
+                    '     %s   _CFFI_OP(%s, %s) },' % (
+                            spaces, op, self._typesdict[fldtype]))
+            self._lsts["field"].append('\n'.join(c_field))
+            #
+            if cname is None:  # unknown name, for _add_missing_struct_unions
+                size_align = (' (size_t)-2, -2, /* unnamed */\n' +
+                    '    _cffi_FIELDS_FOR_%s, %d },' % (approxname,
+                                                        len(enumfields),))
+            else:
+                size_align = ('\n' +
+                    '    sizeof(%s),\n' % (cname,) +
+                    '    offsetof(struct _cffi_align_%s, y),\n'% (approxname,) +
+                    '    _cffi_FIELDS_FOR_%s, %d },' % (approxname,
+                                                        len(enumfields),))
+        else:
+            size_align = ' (size_t)-1, -1, -1, 0 /* %s */ },' % (
+                reason_for_not_expanding,)
+        self._lsts["struct_union"].append(
+            '  { "%s", %d, %s,' % (tp.name, type_index, flags) + size_align)
+        self._seen_struct_unions.add(tp)
+
+    def _add_missing_struct_unions(self):
+        # not very nice, but some struct declarations might be missing
+        # because they don't have any known C name.  Check that they are
+        # not partial (we can't complete or verify them!) and emit them
+        # anonymously.
+        for tp in list(self._struct_unions):
+            if tp not in self._seen_struct_unions:
+                if tp.partial:
+                    raise NotImplementedError("internal inconsistency: %r is "
+                                              "partial but was not seen at "
+                                              "this point" % (tp,))
+                if tp.name.startswith('$') and tp.name[1:].isdigit():
+                    approxname = tp.name[1:]
+                elif tp.name == '_IO_FILE' and tp.forcename == 'FILE':
+                    approxname = 'FILE'
+                    self._typedef_ctx(tp, 'FILE')
+                else:
+                    raise NotImplementedError("internal inconsistency: %r" %
+                                              (tp,))
+                self._struct_ctx(tp, None, approxname)
+
+    def _fix_final_field_list(self, lst):
+        count = 0
+        for i in range(len(lst)):
+            struct_fields = lst[i]
+            pname = struct_fields.split('\n')[0]
+            define_macro = '#define _cffi_FIELDS_FOR_%s  %d' % (pname, count)
+            lst[i] = define_macro + struct_fields[len(pname):]
+            count += lst[i].count('\n  { "')
+
+    def _generate_cpy_struct_collecttype(self, tp, name):
+        self._struct_collecttype(tp)
+    _generate_cpy_union_collecttype = _generate_cpy_struct_collecttype
+
+    def _struct_names(self, tp):
+        cname = tp.get_c_name('')
+        if ' ' in cname:
+            return cname, cname.replace(' ', '_')
+        else:
+            return cname, '_' + cname
+
+    def _generate_cpy_struct_decl(self, tp, name):
+        self._struct_decl(tp, *self._struct_names(tp))
+    _generate_cpy_union_decl = _generate_cpy_struct_decl
+
+    def _generate_cpy_struct_ctx(self, tp, name):
+        self._struct_ctx(tp, *self._struct_names(tp))
+    _generate_cpy_union_ctx = _generate_cpy_struct_ctx
+
+    # ----------
+    # 'anonymous' declarations.  These are produced for anonymous structs
+    # or unions; the 'name' is obtained by a typedef.
+
+    def _generate_cpy_anonymous_collecttype(self, tp, name):
+        if isinstance(tp, model.EnumType):
+            self._generate_cpy_enum_collecttype(tp, name)
+        else:
+            self._struct_collecttype(tp)
+
+    def _generate_cpy_anonymous_decl(self, tp, name):
+        if isinstance(tp, model.EnumType):
+            self._generate_cpy_enum_decl(tp)
+        else:
+            self._struct_decl(tp, name, 'typedef_' + name)
+
+    def _generate_cpy_anonymous_ctx(self, tp, name):
+        if isinstance(tp, model.EnumType):
+            self._enum_ctx(tp, name)
+        else:
+            self._struct_ctx(tp, name, 'typedef_' + name)
+
+    # ----------
+    # constants, declared with "static const ..."
+
+    def _generate_cpy_const(self, is_int, name, tp=None, category='const',
+                            check_value=None):
+        if (category, name) in self._seen_constants:
+            raise ffiplatform.VerificationError(
+                "duplicate declaration of %s '%s'" % (category, name))
+        self._seen_constants.add((category, name))
+        #
+        prnt = self._prnt
+        funcname = '_cffi_%s_%s' % (category, name)
+        if is_int:
+            prnt('static int %s(unsigned long long *o)' % funcname)
+            prnt('{')
+            prnt('  int n = (%s) <= 0;' % (name,))
+            prnt('  *o = (unsigned long long)((%s) << 0);'
+                 '  /* check that we get an integer */' % (name,))
+            if check_value is not None:
+                if check_value > 0:
+                    check_value = '%dU' % (check_value,)
+                prnt('  if (!_cffi_check_int(*o, n, %s))' % (check_value,))
+                prnt('    n |= 2;')
+            prnt('  return n;')
+            prnt('}')
+        else:
+            assert check_value is None
+            prnt('static void %s(char *o)' % funcname)
+            prnt('{')
+            prnt('  *(%s)o = %s;' % (tp.get_c_name('*'), name))
+            prnt('}')
+        prnt()
+
+    def _generate_cpy_constant_collecttype(self, tp, name):
+        is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
+        if not is_int:
+            self._do_collect_type(tp)
+
+    def _generate_cpy_constant_decl(self, tp, name):
+        is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
+        self._generate_cpy_const(is_int, name, tp)
+
+    def _generate_cpy_constant_ctx(self, tp, name):
+        if isinstance(tp, model.PrimitiveType) and tp.is_integer_type():
+            type_op = '_CFFI_OP(_CFFI_OP_CONSTANT_INT, 0)'
+        else:
+            type_index = self._typesdict[tp]
+            type_op = '_CFFI_OP(_CFFI_OP_CONSTANT, %d)' % type_index
+        self._lsts["global"].append(
+            '  { "%s", _cffi_const_%s, %s, 0 },' % (name, name, type_op))
+
+    # ----------
+    # enums
+
+    def _generate_cpy_enum_collecttype(self, tp, name):
+        self._do_collect_type(tp)
+
+    def _generate_cpy_enum_decl(self, tp, name=None):
+        for enumerator in tp.enumerators:
+            self._generate_cpy_const(True, enumerator)
+
+    def _enum_ctx(self, tp, cname):
+        type_index = self._typesdict[tp]
+        type_op = '_CFFI_OP(_CFFI_OP_ENUM, -1)'
+        for enumerator in tp.enumerators:
+            self._lsts["global"].append(
+                '  { "%s", _cffi_const_%s, %s, 0 },' %
+                (enumerator, enumerator, type_op))
+        #
+        if cname is not None and '$' not in cname:
+            size = "sizeof(%s)" % cname
+            signed = "((%s)-1) <= 0" % cname
+        else:
+            basetp = tp.build_baseinttype(self.ffi, [])
+            size = self.ffi.sizeof(basetp)
+            signed = int(int(self.ffi.cast(basetp, -1)) < 0)
+        allenums = ",".join(tp.enumerators)
+        self._lsts["enum"].append(
+            '  { "%s", %d, _cffi_prim_int(%s, %s),\n'
+            '    "%s" },' % (tp.name, type_index, size, signed, allenums))
+
+    def _generate_cpy_enum_ctx(self, tp, name):
+        self._enum_ctx(tp, tp._get_c_name())
+
+    # ----------
+    # macros: for now only for integers
+
+    def _generate_cpy_macro_collecttype(self, tp, name):
+        pass
+
+    def _generate_cpy_macro_decl(self, tp, name):
+        if tp == '...':
+            check_value = None
+        else:
+            check_value = tp     # an integer
+        self._generate_cpy_const(True, name, check_value=check_value)
+
+    def _generate_cpy_macro_ctx(self, tp, name):
+        self._lsts["global"].append(
+            '  { "%s", _cffi_const_%s,'
+            ' _CFFI_OP(_CFFI_OP_CONSTANT_INT, 0), 0 },' % (name, name))
+
+    # ----------
+    # global variables
+
+    def _global_type(self, tp, global_name):
+        if isinstance(tp, model.ArrayType) and tp.length == '...':
+            actual_length = '_cffi_array_len(%s)' % (global_name,)
+            tp = tp.resolve_length(actual_length)
+        return tp
+
+    def _generate_cpy_variable_collecttype(self, tp, name):
+        self._do_collect_type(self._global_type(tp, name))
+
+    def _generate_cpy_variable_decl(self, tp, name):
+        pass
+
+    def _generate_cpy_variable_ctx(self, tp, name):
+        tp = self._global_type(tp, name)
+        type_index = self._typesdict[tp]
+        if tp.sizeof_enabled():
+            size = "sizeof(%s)" % (name,)
+        else:
+            size = "0"
+        self._lsts["global"].append(
+            '  { "%s", &%s, _CFFI_OP(_CFFI_OP_GLOBAL_VAR, %d), %s },'
+            % (name, name, type_index, size))
+
+    # ----------
+    # emitting the opcodes for individual types
+
+    def _emit_bytecode_VoidType(self, tp, index):
+        self.cffi_types[index] = CffiOp(OP_PRIMITIVE, PRIM_VOID)
+
+    def _emit_bytecode_PrimitiveType(self, tp, index):
+        prim_index = PRIMITIVE_TO_INDEX[tp.name]
+        self.cffi_types[index] = CffiOp(OP_PRIMITIVE, prim_index)
+
+    def _emit_bytecode_RawFunctionType(self, tp, index):
+        self.cffi_types[index] = CffiOp(OP_FUNCTION, self._typesdict[tp.result])
+        index += 1
+        for tp1 in tp.args:
+            realindex = self._typesdict[tp1]
+            if index != realindex:
+                if isinstance(tp1, model.PrimitiveType):
+                    self._emit_bytecode_PrimitiveType(tp1, index)
+                else:
+                    self.cffi_types[index] = CffiOp(OP_NOOP, realindex)
+            index += 1
+        self.cffi_types[index] = CffiOp(OP_FUNCTION_END, int(tp.ellipsis))
+
+    def _emit_bytecode_PointerType(self, tp, index):
+        self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[tp.totype])
+
+    _emit_bytecode_ConstPointerType = _emit_bytecode_PointerType
+    _emit_bytecode_NamedPointerType = _emit_bytecode_PointerType
+
+    def _emit_bytecode_FunctionPtrType(self, tp, index):
+        raw = tp.as_raw_function()
+        self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[raw])
+
+    def _emit_bytecode_ArrayType(self, tp, index):
+        item_index = self._typesdict[tp.item]
+        if tp.length is None:
+            self.cffi_types[index] = CffiOp(OP_OPEN_ARRAY, item_index)
+        elif tp.length == '...':
+            raise ffiplatform.VerificationError(
+                "type %s badly placed: the '...' array length can only be "
+                "used on global arrays or on fields of structures" % (
+                    str(tp).replace('/*...*/', '...'),))
+        else:
+            assert self.cffi_types[index + 1] == 'LEN'
+            self.cffi_types[index] = CffiOp(OP_ARRAY, item_index)
+            self.cffi_types[index + 1] = CffiOp(None, str(tp.length))
+
+    def _emit_bytecode_StructType(self, tp, index):
+        struct_index = self._struct_unions[tp]
+        self.cffi_types[index] = CffiOp(OP_STRUCT_UNION, struct_index)
+    _emit_bytecode_UnionType = _emit_bytecode_StructType
+
+    def _emit_bytecode_EnumType(self, tp, index):
+        enum_index = self._enums[tp]
+        self.cffi_types[index] = CffiOp(OP_ENUM, enum_index)
+
+
+if sys.version_info >= (3,):
+    NativeIO = io.StringIO
+else:
+    class NativeIO(io.BytesIO):
+        def write(self, s):
+            if isinstance(s, unicode):
+                s = s.encode('ascii')
+            super(NativeIO, self).write(s)
+
+def make_c_source(ffi, module_name, preamble, target_c_file):
+    recompiler = Recompiler(ffi, module_name)
+    recompiler.collect_type_table()
+    f = NativeIO()
+    recompiler.write_source_to_f(f, preamble)
+    output = f.getvalue()
+    try:
+        with open(target_c_file, 'r') as f1:
+            if f1.read(len(output) + 1) != output:
+                raise IOError
+        return False     # already up-to-date
+    except IOError:
+        with open(target_c_file, 'w') as f1:
+            f1.write(output)
+        return True
+
+def _get_extension(module_name, c_file, kwds):
+    source_name = ffiplatform.maybe_relative_path(c_file)
+    return ffiplatform.get_extension(source_name, module_name, **kwds)
+
+def recompile(ffi, module_name, preamble, tmpdir='.',
+              call_c_compiler=True, c_file=None, **kwds):
+    if not isinstance(module_name, str):
+        module_name = module_name.encode('ascii')
+    if ffi._windows_unicode:
+        ffi._apply_windows_unicode(kwds)
+    if c_file is None:
+        c_file = os.path.join(tmpdir, module_name + '.c')
+    ext = _get_extension(module_name, c_file, kwds)
+    updated = make_c_source(ffi, module_name, preamble, c_file)
+    if call_c_compiler:
+        outputfilename = ffiplatform.compile(tmpdir, ext)
+        return outputfilename
+    else:
+        return ext, updated
+
+def verify(ffi, module_name, preamble, *args, **kwds):
+    from _cffi1.udir import udir
+    import imp
+    assert module_name not in sys.modules, "module name conflict: %r" % (
+        module_name,)
+    kwds.setdefault('tmpdir', str(udir))
+    outputfilename = recompile(ffi, module_name, preamble, *args, **kwds)
+    module = imp.load_dynamic(module_name, outputfilename)
+    #
+    # hack hack hack: copy all *bound methods* from module.ffi back to the
+    # ffi instance.  Then calls like ffi.new() will invoke module.ffi.new().
+    for name in dir(module.ffi):
+        if not name.startswith('_'):
+            attr = getattr(module.ffi, name)
+            if attr is not getattr(ffi, name, object()):
+                setattr(ffi, name, attr)
+    def typeof_disabled(*args, **kwds):
+        raise NotImplementedError
+    ffi._typeof = typeof_disabled
+    return module.lib
diff --git a/lib_pypy/_cffi1/setup.py b/lib_pypy/_cffi1/setup.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/setup.py
@@ -0,0 +1,6 @@
+from distutils.core import setup
+from distutils.extension import Extension
+setup(name='realize_c_type',
+      ext_modules=[Extension(name='realize_c_type',
+                             sources=['realize_c_type.c',
+                                      'parse_c_type.c'])])
diff --git a/lib_pypy/_cffi1/setup_manual.py b/lib_pypy/_cffi1/setup_manual.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/setup_manual.py
@@ -0,0 +1,5 @@
+from distutils.core import setup
+from distutils.extension import Extension
+setup(name='manual',
+      ext_modules=[Extension(name='manual',
+                             sources=['manual.c'])])
diff --git a/lib_pypy/_cffi1/setuptools_ext.py b/lib_pypy/_cffi1/setuptools_ext.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/setuptools_ext.py
@@ -0,0 +1,80 @@
+try:
+    basestring
+except NameError:
+    # Python 3.x
+    basestring = str
+
+def error(msg):
+    from distutils.errors import DistutilsSetupError
+    raise DistutilsSetupError(msg)
+
+
+def add_cffi_module(dist, mod_spec):
+    import os
+    from cffi.api import FFI
+    from _cffi1 import recompiler
+    from distutils.core import Extension
+    from distutils.command.build_ext import build_ext
+    from distutils.dir_util import mkpath
+    from distutils import log
+
+    if not isinstance(mod_spec, basestring):
+        error("argument to 'cffi_modules=...' must be a str or a list of str,"
+              " not %r" % (type(mod_spec).__name__,))
+    mod_spec = str(mod_spec)
+    try:
+        build_mod_name, ffi_var_name = mod_spec.split(':')
+    except ValueError:
+        error("%r must be of the form 'build_mod_name:ffi_variable'" %
+              (mod_spec,))
+    mod = __import__(build_mod_name, None, None, [ffi_var_name])
+    try:
+        ffi = getattr(mod, ffi_var_name)
+    except AttributeError:
+        error("%r: object %r not found in module" % (mod_spec,
+                                                     ffi_var_name))
+    if not isinstance(ffi, FFI):
+        error("%r is not an FFI instance (got %r)" % (mod_spec,
+                                                      type(ffi).__name__))
+    if not hasattr(ffi, '_assigned_source'):
+        error("%r: the set_source() method was not called" % (mod_spec,))
+    module_name = ffi._recompiler_module_name
+    source, kwds = ffi._assigned_source
+    if ffi._windows_unicode:
+        kwds = kwds.copy()
+        ffi._apply_windows_unicode(kwds)
+
+    allsources = ['$PLACEHOLDER']
+    allsources.extend(kwds.get('sources', []))
+    ext = Extension(name=module_name, sources=allsources, **kwds)
+
+    def make_mod(tmpdir):
+        file_name = module_name + '.c'
+        log.info("generating cffi module %r" % file_name)
+        mkpath(tmpdir)
+        c_file = os.path.join(tmpdir, file_name)
+        updated = recompiler.make_c_source(ffi, module_name, source, c_file)
+        if not updated:
+            log.info("already up-to-date")
+        return c_file
+
+    if dist.ext_modules is None:
+        dist.ext_modules = []
+    dist.ext_modules.append(ext)
+
+    base_class = dist.cmdclass.get('build_ext', build_ext)
+    class build_ext_make_mod(base_class):
+        def run(self):
+            if ext.sources[0] == '$PLACEHOLDER':
+                ext.sources[0] = make_mod(self.build_temp)
+            base_class.run(self)
+    dist.cmdclass['build_ext'] = build_ext_make_mod
+
+
+def cffi_modules(dist, attr, value):
+    assert attr == 'cffi_modules'
+    if isinstance(value, basestring):
+        value = [value]
+
+    for cffi_module in value:
+        add_cffi_module(dist, cffi_module)
diff --git a/lib_pypy/_cffi1/support.py b/lib_pypy/_cffi1/support.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/support.py
@@ -0,0 +1,19 @@
+import sys
+
+if sys.version_info < (3,):
+    __all__ = ['u']
+
+    class U(object):
+        def __add__(self, other):
+            return eval('u'+repr(other).replace(r'\\u', r'\u')
+                                       .replace(r'\\U', r'\U'))
+    u = U()
+    assert u+'a\x00b' == eval(r"u'a\x00b'")
+    assert u+'a\u1234b' == eval(r"u'a\u1234b'")
+    assert u+'a\U00012345b' == eval(r"u'a\U00012345b'")
+
+else:
+    __all__ = ['u', 'unicode', 'long']
+    u = ""
+    unicode = str
+    long = int
diff --git a/lib_pypy/_cffi1/test_cffi_binary.py b/lib_pypy/_cffi1/test_cffi_binary.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/test_cffi_binary.py
@@ -0,0 +1,18 @@
+import py, sys, os
+import _cffi_backend
+
+def test_no_unknown_exported_symbols():
+    if not sys.platform.startswith('linux'):
+        py.test.skip("linux-only")
+    g = os.popen("objdump -T '%s'" % _cffi_backend.__file__, 'r')
+    for line in g:
+        if not line.startswith('0'):
+            continue
+        if '*UND*' in line:
+            continue
+        name = line.split()[-1]
+        if name.startswith('_') or name.startswith('.'):
+            continue
+        if name not in ('init_cffi_backend', 'PyInit__cffi_backend'):
+            raise Exception("Unexpected exported name %r" % (name,))
+    g.close()
diff --git a/lib_pypy/_cffi1/test_dlopen.py b/lib_pypy/_cffi1/test_dlopen.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/test_dlopen.py
@@ -0,0 +1,57 @@
+import py
+py.test.skip("later")
+
+from cffi1 import FFI
+import math
+
+
+def test_cdef_struct():
+    ffi = FFI()
+    ffi.cdef("struct foo_s { int a, b; };")
+    assert ffi.sizeof("struct foo_s") == 8
+
+def test_cdef_union():
+    ffi = FFI()
+    ffi.cdef("union foo_s { int a, b; };")
+    assert ffi.sizeof("union foo_s") == 4
+
+def test_cdef_struct_union():
+    ffi = FFI()
+    ffi.cdef("union bar_s { int a; }; struct foo_s { int b; };")
+    assert ffi.sizeof("union bar_s") == 4
+    assert ffi.sizeof("struct foo_s") == 4
+
+def test_cdef_struct_typename_1():
+    ffi = FFI()
+    ffi.cdef("typedef struct { int a; } t1; typedef struct { t1* m; } t2;")
+    assert ffi.sizeof("t2") == ffi.sizeof("void *")
+    assert ffi.sizeof("t1") == 4
+
+def test_cdef_struct_typename_2():
+    ffi = FFI()
+    ffi.cdef("typedef struct { int a; } *p1; typedef struct { p1 m; } *p2;")
+    p2 = ffi.new("p2")
+    assert ffi.sizeof(p2[0]) == ffi.sizeof("void *")
+    assert ffi.sizeof(p2[0].m) == ffi.sizeof("void *")
+
+def test_cdef_struct_anon_1():
+    ffi = FFI()
+    ffi.cdef("typedef struct { int a; } t1; struct foo_s { t1* m; };")
+    assert ffi.sizeof("struct foo_s") == ffi.sizeof("void *")
+
+def test_cdef_struct_anon_2():
+    ffi = FFI()
+    ffi.cdef("typedef struct { int a; } *p1; struct foo_s { p1 m; };")
+    assert ffi.sizeof("struct foo_s") == ffi.sizeof("void *")
+
+def test_cdef_struct_anon_3():
+    ffi = FFI()
+    ffi.cdef("typedef struct { int a; } **pp; struct foo_s { pp m; };")
+    assert ffi.sizeof("struct foo_s") == ffi.sizeof("void *")
+
+def test_math_sin():
+    ffi = FFI()
+    ffi.cdef("double sin(double);")
+    m = ffi.dlopen('m')
+    x = m.sin(1.23)
+    assert x == math.sin(1.23)
diff --git a/lib_pypy/_cffi1/test_ffi_obj.py b/lib_pypy/_cffi1/test_ffi_obj.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/test_ffi_obj.py
@@ -0,0 +1,159 @@
+import py
+import _cffi_backend as _cffi1_backend
+
+
+def test_ffi_new():
+    ffi = _cffi1_backend.FFI()
+    p = ffi.new("int *")
+    p[0] = -42
+    assert p[0] == -42
+
+def test_ffi_subclass():
+    class FOO(_cffi1_backend.FFI):
+        def __init__(self, x):
+            self.x = x
+    foo = FOO(42)
+    assert foo.x == 42
+    p = foo.new("int *")
+    assert p[0] == 0
+
+def test_ffi_no_argument():
+    py.test.raises(TypeError, _cffi1_backend.FFI, 42)
+
+def test_ffi_cache_type():
+    ffi = _cffi1_backend.FFI()
+    t1 = ffi.typeof("int **")
+    t2 = ffi.typeof("int *")
+    assert t2.item is t1.item.item
+    assert t2 is t1.item
+    assert ffi.typeof("int[][10]") is ffi.typeof("int[][10]")
+    assert ffi.typeof("int(*)()") is ffi.typeof("int(*)()")
+
+def test_ffi_cache_type_globally():
+    ffi1 = _cffi1_backend.FFI()
+    ffi2 = _cffi1_backend.FFI()
+    t1 = ffi1.typeof("int *")
+    t2 = ffi2.typeof("int *")
+    assert t1 is t2
+
+def test_ffi_invalid():
+    ffi = _cffi1_backend.FFI()
+    # array of 10 times an "int[]" is invalid
+    py.test.raises(ValueError, ffi.typeof, "int[10][]")
+
+def test_ffi_docstrings():
+    # check that all methods of the FFI class have a docstring.
+    check_type = type(_cffi1_backend.FFI.new)
+    for methname in dir(_cffi1_backend.FFI):
+        if not methname.startswith('_'):
+            method = getattr(_cffi1_backend.FFI, methname)
+            if isinstance(method, check_type):
+                assert method.__doc__, "method FFI.%s() has no docstring" % (
+                    methname,)
+
+def test_ffi_NULL():
+    NULL = _cffi1_backend.FFI.NULL
+    assert _cffi1_backend.FFI().typeof(NULL).cname == "void *"
+
+def test_ffi_no_attr():
+    ffi = _cffi1_backend.FFI()
+    py.test.raises(AttributeError, "ffi.no_such_name")
+    py.test.raises(AttributeError, "ffi.no_such_name = 42")
+    py.test.raises(AttributeError, "del ffi.no_such_name")
+
+def test_ffi_string():
+    ffi = _cffi1_backend.FFI()
+    p = ffi.new("char[]", init=b"foobar\x00baz")
+    assert ffi.string(p) == b"foobar"
+
+def test_ffi_errno():
+    # xxx not really checking errno, just checking that we can read/write it
+    ffi = _cffi1_backend.FFI()
+    ffi.errno = 42
+    assert ffi.errno == 42
+
+def test_ffi_alignof():
+    ffi = _cffi1_backend.FFI()
+    assert ffi.alignof("int") == 4
+    assert ffi.alignof("int[]") == 4
+    assert ffi.alignof("int[41]") == 4
+    assert ffi.alignof("short[41]") == 2
+    assert ffi.alignof(ffi.new("int[41]")) == 4
+    assert ffi.alignof(ffi.new("int[]", 41)) == 4
+
+def test_ffi_sizeof():
+    ffi = _cffi1_backend.FFI()
+    assert ffi.sizeof("int") == 4
+    py.test.raises(ffi.error, ffi.sizeof, "int[]")
+    assert ffi.sizeof("int[41]") == 41 * 4
+    assert ffi.sizeof(ffi.new("int[41]")) == 41 * 4
+    assert ffi.sizeof(ffi.new("int[]", 41)) == 41 * 4
+
+def test_ffi_callback():
+    ffi = _cffi1_backend.FFI()
+    assert ffi.callback("int(int)", lambda x: x + 42)(10) == 52
+    assert ffi.callback("int(*)(int)", lambda x: x + 42)(10) == 52
+    assert ffi.callback("int(int)", lambda x: x + "", -66)(10) == -66
+    assert ffi.callback("int(int)", lambda x: x + "", error=-66)(10) == -66
+
+def test_ffi_callback_decorator():
+    ffi = _cffi1_backend.FFI()
+    assert ffi.callback(ffi.typeof("int(*)(int)"))(lambda x: x + 42)(10) == 52
+    deco = ffi.callback("int(int)", error=-66)
+    assert deco(lambda x: x + "")(10) == -66
+    assert deco(lambda x: x + 42)(10) == 52
+
+def test_ffi_getctype():
+    ffi = _cffi1_backend.FFI()
+    assert ffi.getctype("int") == "int"
+    assert ffi.getctype("int", 'x') == "int x"
+    assert ffi.getctype("int*") == "int *"
+    assert ffi.getctype("int*", '') == "int *"
+    assert ffi.getctype("int*", 'x') == "int * x"
+    assert ffi.getctype("int", '*') == "int *"
+    assert ffi.getctype("int", replace_with=' * x ') == "int * x"
+    assert ffi.getctype(ffi.typeof("int*"), '*') == "int * *"
+    assert ffi.getctype("int", '[5]') == "int[5]"
+    assert ffi.getctype("int[5]", '[6]') == "int[6][5]"
+    assert ffi.getctype("int[5]", '(*)') == "int(*)[5]"
+    # special-case for convenience: automatically put '()' around '*'
+    assert ffi.getctype("int[5]", '*') == "int(*)[5]"
+    assert ffi.getctype("int[5]", '*foo') == "int(*foo)[5]"
+    assert ffi.getctype("int[5]", ' ** foo ') == "int(** foo)[5]"
+
+def test_addressof():
+    ffi = _cffi1_backend.FFI()
+    a = ffi.new("int[10]")
+    b = ffi.addressof(a, 5)
+    b[2] = -123
+    assert a[7] == -123
+
+def test_handle():
+    ffi = _cffi1_backend.FFI()
+    x = [2, 4, 6]
+    xp = ffi.new_handle(x)
+    assert ffi.typeof(xp) == ffi.typeof("void *")
+    assert ffi.from_handle(xp) is x
+    yp = ffi.new_handle([6, 4, 2])
+    assert ffi.from_handle(yp) == [6, 4, 2]
+
+def test_ffi_cast():
+    ffi = _cffi1_backend.FFI()
+    assert ffi.cast("int(*)(int)", 0) == ffi.NULL
+    ffi.callback("int(int)")      # side-effect of registering this string
+    py.test.raises(ffi.error, ffi.cast, "int(int)", 0)
+
+def test_ffi_invalid_type():
+    ffi = _cffi1_backend.FFI()
+    e = py.test.raises(ffi.error, ffi.cast, "", 0)
+    assert str(e.value) == ("identifier expected\n"
+                            "\n"
+                            "^")
+    e = py.test.raises(ffi.error, ffi.cast, "struct struct", 0)
+    assert str(e.value) == ("struct or union name expected\n"
+                            "struct struct\n"
+                            "       ^")
+    e = py.test.raises(ffi.error, ffi.cast, "struct never_heard_of_s", 0)
+    assert str(e.value) == ("undefined struct/union name\n"
+                            "struct never_heard_of_s\n"
+                            "       ^")
diff --git a/lib_pypy/_cffi1/test_new_ffi_1.py b/lib_pypy/_cffi1/test_new_ffi_1.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi1/test_new_ffi_1.py
@@ -0,0 +1,1658 @@
+import py
+import platform, imp
+import sys, os, ctypes
+import cffi
+from .udir import udir
+from .recompiler import recompile
+from .support import *
+
+SIZE_OF_INT   = ctypes.sizeof(ctypes.c_int)
+SIZE_OF_LONG  = ctypes.sizeof(ctypes.c_long)
+SIZE_OF_SHORT = ctypes.sizeof(ctypes.c_short)
+SIZE_OF_PTR   = ctypes.sizeof(ctypes.c_void_p)
+SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar)
+
+
+def setup_module():
+    global ffi, construction_params
+    ffi1 = cffi.FFI()
+    DEFS = r"""
+        struct repr { short a, b, c; };
+        struct simple { int a; short b, c; };
+        struct array { int a[2]; char b[3]; };
+        struct recursive { int value; struct recursive *next; };
+        union simple_u { int a; short b, c; };
+        union init_u { char a; int b; };
+        struct four_s { int a; short b, c, d; };
+        union four_u { int a; short b, c, d; };
+        struct string { const char *name; };
+        struct ustring { const wchar_t *name; };
+        struct voidp { void *p; int *q; short *r; };
+        struct ab { int a, b; };
+        struct abc { int a, b, c; };
+
+        enum foq { A0, B0, CC0, D0 };
+        enum bar { A1, B1=-2, CC1, D1, E1 };
+        enum baz { A2=0x1000, B2=0x2000 };
+        enum foo2 { A3, B3, C3, D3 };
+        struct bar_with_e { enum foo2 e; };
+        enum noncont { A4, B4=42, C4 };
+        enum etypes {A5='!', B5='\'', C5=0x10, D5=010, E5=- 0x10, F5=-010};
+        typedef enum { Value0 = 0 } e_t, *pe_t;
+        enum e_noninj { AA3=0, BB3=0, CC3=0, DD3=0 };
+        enum e_prev { AA4, BB4=2, CC4=4, DD4=BB4, EE4, FF4=CC4, GG4=FF4 };
+
+        struct nesting { struct abc d, e; };
+        struct array2 { int a, b; int c[99]; };
+        struct align { char a; short b; char c; };
+        struct bitfield { int a:10, b:20, c:3; };
+        typedef enum { AA2, BB2, CC2 } foo_e_t;
+        typedef struct { foo_e_t f:2; } bfenum_t;
+        typedef struct { int a; } anon_foo_t;
+        typedef struct { char b, c; } anon_bar_t;
+        typedef struct named_foo_s { int a; } named_foo_t, *named_foo_p;
+        typedef struct { int a; } unnamed_foo_t, *unnamed_foo_p;
+        struct nonpacked { char a; int b; };
+        struct array0 { int len; short data[0]; };
+        struct array_no_length { int x; int a[]; };
+
+        struct nested_anon {
+            struct { int a, b; };
+            union { int c, d; };
+        };
+        struct nested_field_ofs_s {
+            struct { int a; char b; };
+            union { char c; };
+        };
+        union nested_anon_u {
+            struct { int a, b; };
+            union { int c, d; };
+        };
+        struct abc50 { int a, b; int c[50]; };
+        struct ints_and_bitfield { int a,b,c,d,e; int x:1; };
+    """
+    DEFS_PACKED = """
+        struct is_packed { char a; int b; } /*here*/;
+    """
+    if sys.platform == "win32":
+        DEFS = DEFS.replace('data[0]', 'data[1]')   # not supported
+        CCODE = (DEFS + "\n#pragma pack(push,1)\n" + DEFS_PACKED +
+                 "\n#pragma pack(pop)\n")
+    else:
+        CCODE = (DEFS +
+                 DEFS_PACKED.replace('/*here*/', '__attribute__((packed))'))
+
+    ffi1.cdef(DEFS)
+    ffi1.cdef(DEFS_PACKED, packed=True)
+
+    outputfilename = recompile(ffi1, "test_new_ffi_1", CCODE,
+                               tmpdir=str(udir))
+    module = imp.load_dynamic("test_new_ffi_1", outputfilename)
+    ffi = module.ffi
+    construction_params = (ffi1, CCODE)
+
+
+class TestNewFFI1:
+
+    def test_integer_ranges(self):
+        for (c_type, size) in [('char', 1),
+                               ('short', 2),
+                               ('short int', 2),
+                               ('', 4),
+                               ('int', 4),
+                               ('long', SIZE_OF_LONG),
+                               ('long int', SIZE_OF_LONG),
+                               ('long long', 8),
+                               ('long long int', 8),
+                               ]:
+            for unsigned in [None, False, True]:
+                c_decl = {None: '',
+                          False: 'signed ',
+                          True: 'unsigned '}[unsigned] + c_type
+                if c_decl == 'char' or c_decl == '':
+                    continue
+                self._test_int_type(ffi, c_decl, size, unsigned)
+
+    def test_fixedsize_int(self):
+        for size in [1, 2, 4, 8]:
+            self._test_int_type(ffi, 'int%d_t' % (8*size), size, False)
+            self._test_int_type(ffi, 'uint%d_t' % (8*size), size, True)
+        self._test_int_type(ffi, 'intptr_t', SIZE_OF_PTR, False)
+        self._test_int_type(ffi, 'uintptr_t', SIZE_OF_PTR, True)
+        self._test_int_type(ffi, 'ptrdiff_t', SIZE_OF_PTR, False)
+        self._test_int_type(ffi, 'size_t', SIZE_OF_PTR, True)
+        self._test_int_type(ffi, 'ssize_t', SIZE_OF_PTR, False)
+
+    def _test_int_type(self, ffi, c_decl, size, unsigned):
+        if unsigned:
+            min = 0
+            max = (1 << (8*size)) - 1
+        else:
+            min = -(1 << (8*size-1))
+            max = (1 << (8*size-1)) - 1
+        min = int(min)
+        max = int(max)
+        p = ffi.cast(c_decl, min)
+        assert p != min       # no __eq__(int)
+        assert bool(p) is True
+        assert int(p) == min
+        p = ffi.cast(c_decl, max)
+        assert int(p) == max
+        p = ffi.cast(c_decl, long(max))
+        assert int(p) == max
+        q = ffi.cast(c_decl, min - 1)
+        assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
+        q = ffi.cast(c_decl, long(min - 1))
+        assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
+        assert q != p
+        assert int(q) == int(p)
+        assert hash(q) != hash(p)   # unlikely
+        c_decl_ptr = '%s *' % c_decl
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, min - 1)
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, max + 1)
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(min - 1))
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(max + 1))
+        assert ffi.new(c_decl_ptr, min)[0] == min
+        assert ffi.new(c_decl_ptr, max)[0] == max
+        assert ffi.new(c_decl_ptr, long(min))[0] == min
+        assert ffi.new(c_decl_ptr, long(max))[0] == max
+
+    def test_new_unsupported_type(self):
+        e = py.test.raises(TypeError, ffi.new, "int")
+        assert str(e.value) == "expected a pointer or array ctype, got 'int'"
+
+    def test_new_single_integer(self):
+        p = ffi.new("int *")     # similar to ffi.new("int[1]")
+        assert p[0] == 0
+        p[0] = -123
+        assert p[0] == -123
+        p = ffi.new("int *", -42)
+        assert p[0] == -42
+        assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
+
+    def test_new_array_no_arg(self):
+        p = ffi.new("int[10]")
+        # the object was zero-initialized:
+        for i in range(10):
+            assert p[i] == 0
+
+    def test_array_indexing(self):
+        p = ffi.new("int[10]")
+        p[0] = 42
+        p[9] = 43
+        assert p[0] == 42
+        assert p[9] == 43
+        py.test.raises(IndexError, "p[10]")
+        py.test.raises(IndexError, "p[10] = 44")
+        py.test.raises(IndexError, "p[-1]")
+        py.test.raises(IndexError, "p[-1] = 44")
+
+    def test_new_array_args(self):
+        # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}"
+        # then here we must enclose the items in a list
+        p = ffi.new("int[5]", [10, 20, 30, 40, 50])
+        assert p[0] == 10
+        assert p[1] == 20
+        assert p[2] == 30
+        assert p[3] == 40
+        assert p[4] == 50
+        p = ffi.new("int[4]", [25])
+        assert p[0] == 25
+        assert p[1] == 0     # follow C convention rather than LuaJIT's
+        assert p[2] == 0
+        assert p[3] == 0
+        p = ffi.new("int[4]", [ffi.cast("int", -5)])
+        assert p[0] == -5
+        assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4*SIZE_OF_INT)
+
+    def test_new_array_varsize(self):
+        p = ffi.new("int[]", 10)     # a single integer is the length
+        assert p[9] == 0
+        py.test.raises(IndexError, "p[10]")
+        #
+        py.test.raises(TypeError, ffi.new, "int[]")
+        #
+        p = ffi.new("int[]", [-6, -7])    # a list is all the items, like C
+        assert p[0] == -6
+        assert p[1] == -7
+        py.test.raises(IndexError, "p[2]")
+        assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT)
+        #
+        p = ffi.new("int[]", 0)
+        py.test.raises(IndexError, "p[0]")
+        py.test.raises(ValueError, ffi.new, "int[]", -1)
+        assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
+
+    def test_pointer_init(self):
+        n = ffi.new("int *", 24)
+        a = ffi.new("int *[10]", [ffi.NULL, ffi.NULL, n, n, ffi.NULL])
+        for i in range(10):
+            if i not in (2, 3):
+                assert a[i] == ffi.NULL
+        assert a[2] == a[3] == n
+
+    def test_cannot_cast(self):
+        a = ffi.new("short int[10]")
+        e = py.test.raises(TypeError, ffi.new, "long int **", a)
+        msg = str(e.value)
+        assert "'short[10]'" in msg and "'long *'" in msg
+
+    def test_new_pointer_to_array(self):
+        a = ffi.new("int[4]", [100, 102, 104, 106])
+        p = ffi.new("int **", a)
+        assert p[0] == ffi.cast("int *", a)
+        assert p[0][2] == 104
+        p = ffi.cast("int *", a)
+        assert p[0] == 100
+        assert p[1] == 102
+        assert p[2] == 104
+        assert p[3] == 106
+        # keepalive: a
+
+    def test_pointer_direct(self):
+        p = ffi.cast("int*", 0)
+        assert p is not None
+        assert bool(p) is False
+        assert p == ffi.cast("int*", 0)
+        assert p != None
+        assert repr(p) == "<cdata 'int *' NULL>"
+        a = ffi.new("int[]", [123, 456])
+        p = ffi.cast("int*", a)
+        assert bool(p) is True
+        assert p == ffi.cast("int*", a)
+        assert p != ffi.cast("int*", 0)
+        assert p[0] == 123
+        assert p[1] == 456
+
+    def test_repr(self):
+        typerepr = "<ctype '%s'>"
+        p = ffi.cast("short unsigned int", 0)
+        assert repr(p) == "<cdata 'unsigned short' 0>"
+        assert repr(ffi.typeof(p)) == typerepr % "unsigned short"
+        p = ffi.cast("unsigned short int", 0)
+        assert repr(p) == "<cdata 'unsigned short' 0>"
+        assert repr(ffi.typeof(p)) == typerepr % "unsigned short"
+        p = ffi.cast("int*", 0)
+        assert repr(p) == "<cdata 'int *' NULL>"
+        assert repr(ffi.typeof(p)) == typerepr % "int *"
+        #
+        p = ffi.new("int*")
+        assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
+        assert repr(ffi.typeof(p)) == typerepr % "int *"
+        p = ffi.new("int**")
+        assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR
+        assert repr(ffi.typeof(p)) == typerepr % "int * *"
+        p = ffi.new("int [2]")
+        assert repr(p) == "<cdata 'int[2]' owning %d bytes>" % (2*SIZE_OF_INT)
+        assert repr(ffi.typeof(p)) == typerepr % "int[2]"
+        p = ffi.new("int*[2][3]")
+        assert repr(p) == "<cdata 'int *[2][3]' owning %d bytes>" % (
+            6*SIZE_OF_PTR)
+        assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]"
+        p = ffi.new("struct repr *")
+        assert repr(p) == "<cdata 'struct repr *' owning %d bytes>" % (
+            3*SIZE_OF_SHORT)
+        assert repr(ffi.typeof(p)) == typerepr % "struct repr *"
+        #
+        q = ffi.cast("short", -123)
+        assert repr(q) == "<cdata 'short' -123>"
+        assert repr(ffi.typeof(q)) == typerepr % "short"
+        p = ffi.new("int*")
+        q = ffi.cast("short*", p)
+        assert repr(q).startswith("<cdata 'short *' 0x")
+        assert repr(ffi.typeof(q)) == typerepr % "short *"
+        p = ffi.new("int [2]")
+        q = ffi.cast("int*", p)
+        assert repr(q).startswith("<cdata 'int *' 0x")
+        assert repr(ffi.typeof(q)) == typerepr % "int *"
+        p = ffi.new("struct repr*")
+        q = ffi.cast("struct repr *", p)
+        assert repr(q).startswith("<cdata 'struct repr *' 0x")
+        assert repr(ffi.typeof(q)) == typerepr % "struct repr *"
+        prevrepr = repr(q)
+        q = q[0]
+        assert repr(q) == prevrepr.replace(' *', ' &')
+        assert repr(ffi.typeof(q)) == typerepr % "struct repr"
+
+    def test_new_array_of_array(self):
+        p = ffi.new("int[3][4]")
+        p[0][0] = 10
+        p[2][3] = 33
+        assert p[0][0] == 10
+        assert p[2][3] == 33
+        py.test.raises(IndexError, "p[1][-1]")
+
+    def test_constructor_array_of_array(self):
+        p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]])
+        assert p[2][1] == 15
+
+    def test_new_array_of_pointer_1(self):
+        n = ffi.new("int*", 99)
+        p = ffi.new("int*[4]")
+        p[3] = n
+        a = p[3]
+        assert repr(a).startswith("<cdata 'int *' 0x")
+        assert a[0] == 99
+
+    def test_new_array_of_pointer_2(self):
+        n = ffi.new("int[1]", [99])
+        p = ffi.new("int*[4]")
+        p[3] = n
+        a = p[3]
+        assert repr(a).startswith("<cdata 'int *' 0x")
+        assert a[0] == 99
+
+    def test_char(self):
+        assert ffi.new("char*", b"\xff")[0] == b'\xff'
+        assert ffi.new("char*")[0] == b'\x00'
+        assert int(ffi.cast("char", 300)) == 300 - 256
+        assert bool(ffi.cast("char", 0))
+        py.test.raises(TypeError, ffi.new, "char*", 32)
+        py.test.raises(TypeError, ffi.new, "char*", u+"x")
+        py.test.raises(TypeError, ffi.new, "char*", b"foo")
+        #
+        p = ffi.new("char[]", [b'a', b'b', b'\x9c'])
+        assert len(p) == 3
+        assert p[0] == b'a'
+        assert p[1] == b'b'
+        assert p[2] == b'\x9c'
+        p[0] = b'\xff'
+        assert p[0] == b'\xff'
+        p = ffi.new("char[]", b"abcd")
+        assert len(p) == 5
+        assert p[4] == b'\x00'    # like in C, with:  char[] p = "abcd";
+        #
+        p = ffi.new("char[4]", b"ab")
+        assert len(p) == 4
+        assert [p[i] for i in range(4)] == [b'a', b'b', b'\x00', b'\x00']
+        p = ffi.new("char[2]", b"ab")
+        assert len(p) == 2
+        assert [p[i] for i in range(2)] == [b'a', b'b']
+        py.test.raises(IndexError, ffi.new, "char[2]", b"abc")
+
+    def check_wchar_t(self, ffi):
+        try:
+            ffi.cast("wchar_t", 0)
+        except NotImplementedError:
+            py.test.skip("NotImplementedError: wchar_t")
+
+    def test_wchar_t(self):
+        self.check_wchar_t(ffi)
+        assert ffi.new("wchar_t*", u+'x')[0] == u+'x'
+        assert ffi.new("wchar_t*", u+'\u1234')[0] == u+'\u1234'
+        if SIZE_OF_WCHAR > 2:
+            assert ffi.new("wchar_t*", u+'\U00012345')[0] == u+'\U00012345'
+        else:
+            py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345')
+        assert ffi.new("wchar_t*")[0] == u+'\x00'
+        assert int(ffi.cast("wchar_t", 300)) == 300
+        assert bool(ffi.cast("wchar_t", 0))
+        py.test.raises(TypeError, ffi.new, "wchar_t*", 32)
+        py.test.raises(TypeError, ffi.new, "wchar_t*", "foo")
+        #
+        p = ffi.new("wchar_t[]", [u+'a', u+'b', u+'\u1234'])
+        assert len(p) == 3
+        assert p[0] == u+'a'
+        assert p[1] == u+'b' and type(p[1]) is unicode
+        assert p[2] == u+'\u1234'
+        p[0] = u+'x'
+        assert p[0] == u+'x' and type(p[0]) is unicode
+        p[1] = u+'\u1357'
+        assert p[1] == u+'\u1357'
+        p = ffi.new("wchar_t[]", u+"abcd")
+        assert len(p) == 5
+        assert p[4] == u+'\x00'
+        p = ffi.new("wchar_t[]", u+"a\u1234b")
+        assert len(p) == 4
+        assert p[1] == u+'\u1234'
+        #
+        p = ffi.new("wchar_t[]", u+'\U00023456')
+        if SIZE_OF_WCHAR == 2:
+            assert sys.maxunicode == 0xffff
+            assert len(p) == 3
+            assert p[0] == u+'\ud84d'
+            assert p[1] == u+'\udc56'
+            assert p[2] == u+'\x00'
+        else:
+            assert len(p) == 2
+            assert p[0] == u+'\U00023456'
+            assert p[1] == u+'\x00'
+        #
+        p = ffi.new("wchar_t[4]", u+"ab")
+        assert len(p) == 4
+        assert [p[i] for i in range(4)] == [u+'a', u+'b', u+'\x00', u+'\x00']
+        p = ffi.new("wchar_t[2]", u+"ab")
+        assert len(p) == 2
+        assert [p[i] for i in range(2)] == [u+'a', u+'b']
+        py.test.raises(IndexError, ffi.new, "wchar_t[2]", u+"abc")
+
+    def test_none_as_null_doesnt_work(self):
+        p = ffi.new("int*[1]")
+        assert p[0] is not None
+        assert p[0] != None
+        assert p[0] == ffi.NULL
+        assert repr(p[0]) == "<cdata 'int *' NULL>"
+        #
+        n = ffi.new("int*", 99)
+        p = ffi.new("int*[]", [n])
+        assert p[0][0] == 99
+        py.test.raises(TypeError, "p[0] = None")
+        p[0] = ffi.NULL
+        assert p[0] == ffi.NULL
+
+    def test_float(self):
+        p = ffi.new("float[]", [-2, -2.5])
+        assert p[0] == -2.0
+        assert p[1] == -2.5
+        p[1] += 17.75
+        assert p[1] == 15.25
+        #
+        p = ffi.new("float*", 15.75)
+        assert p[0] == 15.75
+        py.test.raises(TypeError, int, p)
+        py.test.raises(TypeError, float, p)
+        p[0] = 0.0
+        assert bool(p) is True
+        #
+        p = ffi.new("float*", 1.1)
+        f = p[0]
+        assert f != 1.1      # because of rounding effect
+        assert abs(f - 1.1) < 1E-7
+        #
+        INF = 1E200 * 1E200
+        assert 1E200 != INF
+        p[0] = 1E200
+        assert p[0] == INF     # infinite, not enough precision
+
+    def test_struct_simple(self):
+        s = ffi.new("struct simple*")
+        assert s.a == s.b == s.c == 0
+        s.b = -23
+        assert s.b == -23
+        py.test.raises(OverflowError, "s.b = 32768")
+        #
+        s = ffi.new("struct simple*", [-2, -3])
+        assert s.a == -2
+        assert s.b == -3
+        assert s.c == 0
+        py.test.raises((AttributeError, TypeError), "del s.a")
+        assert repr(s) == "<cdata 'struct simple *' owning %d bytes>" % (
+            SIZE_OF_INT + 2 * SIZE_OF_SHORT)
+        #
+        py.test.raises(ValueError, ffi.new, "struct simple*", [1, 2, 3, 4])
+
+    def test_constructor_struct_from_dict(self):
+        s = ffi.new("struct simple*", {'b': 123, 'c': 456})
+        assert s.a == 0
+        assert s.b == 123
+        assert s.c == 456
+        py.test.raises(KeyError, ffi.new, "struct simple*", {'d': 456})
+
+    def test_struct_pointer(self):
+        s = ffi.new("struct simple*")
+        assert s[0].a == s[0].b == s[0].c == 0
+        s[0].b = -23
+        assert s[0].b == s.b == -23
+        py.test.raises(OverflowError, "s[0].b = -32769")
+        py.test.raises(IndexError, "s[1]")
+
+    def test_struct_opaque(self):
+        py.test.raises(ffi.error, ffi.new, "struct baz*")
+        # should 'ffi.new("struct baz **") work?  it used to, but it was
+        # not particularly useful...
+        py.test.raises(ffi.error, ffi.new, "struct baz**")
+
+    def test_pointer_to_struct(self):
+        s = ffi.new("struct simple *")
+        s.a = -42
+        assert s[0].a == -42
+        p = ffi.new("struct simple **", s)
+        assert p[0].a == -42
+        assert p[0][0].a == -42
+        p[0].a = -43
+        assert s.a == -43
+        assert s[0].a == -43
+        p[0][0].a = -44
+        assert s.a == -44
+        assert s[0].a == -44
+        s.a = -45
+        assert p[0].a == -45
+        assert p[0][0].a == -45
+        s[0].a = -46
+        assert p[0].a == -46
+        assert p[0][0].a == -46
+
+    def test_constructor_struct_of_array(self):
+        s = ffi.new("struct array *", [[10, 11], [b'a', b'b', b'c']])
+        assert s.a[1] == 11
+        assert s.b[2] == b'c'
+        s.b[1] = b'X'
+        assert s.b[0] == b'a'
+        assert s.b[1] == b'X'
+        assert s.b[2] == b'c'
+
+    def test_recursive_struct(self):
+        s = ffi.new("struct recursive*")
+        t = ffi.new("struct recursive*")
+        s.value = 123
+        s.next = t
+        t.value = 456
+        assert s.value == 123
+        assert s.next.value == 456
+
+    def test_union_simple(self):
+        u = ffi.new("union simple_u*")
+        assert u.a == u.b == u.c == 0
+        u.b = -23
+        assert u.b == -23
+        assert u.a != 0
+        py.test.raises(OverflowError, "u.b = 32768")
+        #


More information about the pypy-commit mailing list