[pypy-commit] pypy propogate-nans: merge default into branch

mattip noreply at buildbot.pypy.org
Sun Nov 8 13:10:59 EST 2015


Author: mattip <matti.picus at gmail.com>
Branch: propogate-nans
Changeset: r80590:2d4bc6d7641d
Date: 2015-11-08 19:50 +0200
http://bitbucket.org/pypy/pypy/changeset/2d4bc6d7641d/

Log:	merge default into branch

diff too long, truncating to 2000 out of 2541 lines

diff --git a/lib_pypy/_tkinter/tklib_build.py b/lib_pypy/_tkinter/tklib_build.py
--- a/lib_pypy/_tkinter/tklib_build.py
+++ b/lib_pypy/_tkinter/tklib_build.py
@@ -212,8 +212,8 @@
 #include <tclTomMath.h>
 #endif 
 
-char *get_tk_version() { return TK_VERSION; }
-char *get_tcl_version() { return TCL_VERSION; }
+char *get_tk_version(void) { return TK_VERSION; }
+char *get_tcl_version(void) { return TCL_VERSION; }
 """ % globals(),
 include_dirs=incdirs,
 libraries=linklibs,
diff --git a/lib_pypy/cffi/cffi_opcode.py b/lib_pypy/cffi/cffi_opcode.py
--- a/lib_pypy/cffi/cffi_opcode.py
+++ b/lib_pypy/cffi/cffi_opcode.py
@@ -110,6 +110,8 @@
 _UNKNOWN_FLOAT_PRIM    = -2
 _UNKNOWN_LONG_DOUBLE   = -3
 
+_IO_FILE_STRUCT        = -1
+
 PRIMITIVE_TO_INDEX = {
     'char':               PRIM_CHAR,
     'short':              PRIM_SHORT,
diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py
--- a/lib_pypy/cffi/commontypes.py
+++ b/lib_pypy/cffi/commontypes.py
@@ -2,10 +2,17 @@
 from . import api, model
 
 
-COMMON_TYPES = {
-    'FILE': model.unknown_type('FILE', '_IO_FILE'),
-    'bool': '_Bool',
-    }
+COMMON_TYPES = {}
+
+try:
+    # fetch "bool" and all simple Windows types
+    from _cffi_backend import _get_common_types
+    _get_common_types(COMMON_TYPES)
+except ImportError:
+    pass
+
+COMMON_TYPES['FILE'] = model.unknown_type('FILE', '_IO_FILE')
+COMMON_TYPES['bool'] = '_Bool'    # in case we got ImportError above
 
 for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
     if _type.endswith('_t'):
@@ -14,212 +21,35 @@
 
 _CACHE = {}
 
-def resolve_common_type(commontype):
+def resolve_common_type(parser, commontype):
     try:
         return _CACHE[commontype]
     except KeyError:
-        result = COMMON_TYPES.get(commontype, commontype)
-        if not isinstance(result, str):
-            pass    # result is already a BaseType
-        elif result.endswith(' *'):
-            if result.startswith('const '):
-                result = model.ConstPointerType(
-                    resolve_common_type(result[6:-2]))
-            else:
-                result = model.PointerType(resolve_common_type(result[:-2]))
-        elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
-            result = model.PrimitiveType(result)
-        elif result == 'set-unicode-needed':
+        cdecl = COMMON_TYPES.get(commontype, commontype)
+        if not isinstance(cdecl, str):
+            result, quals = cdecl, 0    # cdecl is already a BaseType
+        elif cdecl in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
+            result, quals = model.PrimitiveType(cdecl), 0
+        elif cdecl == 'set-unicode-needed':
             raise api.FFIError("The Windows type %r is only available after "
                                "you call ffi.set_unicode()" % (commontype,))
         else:
-            if commontype == result:
+            if commontype == cdecl:
                 raise api.FFIError("Unsupported type: %r.  Please file a bug "
                                    "if you think it should be." % (commontype,))
-            result = resolve_common_type(result)   # recursively
+            result, quals = parser.parse_type_and_quals(cdecl)   # recursive
+
         assert isinstance(result, model.BaseTypeByIdentity)
-        _CACHE[commontype] = result
-        return result
+        _CACHE[commontype] = result, quals
+        return result, quals
 
 
 # ____________________________________________________________
-# Windows common types
+# extra types for Windows (most of them are in commontypes.c)
 
 
-def win_common_types(maxsize):
-    result = {}
-    if maxsize < (1<<32):
-        result.update({      # Windows 32-bits
-            'HALF_PTR': 'short',
-            'INT_PTR': 'int',
-            'LONG_PTR': 'long',
-            'UHALF_PTR': 'unsigned short',
-            'UINT_PTR': 'unsigned int',
-            'ULONG_PTR': 'unsigned long',
-            })
-    else:
-        result.update({      # Windows 64-bits
-            'HALF_PTR': 'int',
-            'INT_PTR': 'long long',
-            'LONG_PTR': 'long long',
-            'UHALF_PTR': 'unsigned int',
-            'UINT_PTR': 'unsigned long long',
-            'ULONG_PTR': 'unsigned long long',
-            })
-    result.update({
-        "BYTE": "unsigned char",
-        "BOOL": "int",
-        "CCHAR": "char",
-        "CHAR": "char",
-        "DWORD": "unsigned long",
-        "DWORD32": "unsigned int",
-        "DWORD64": "unsigned long long",
-        "FLOAT": "float",
-        "INT": "int",
-        "INT8": "signed char",
-        "INT16": "short",
-        "INT32": "int",
-        "INT64": "long long",
-        "LONG": "long",
-        "LONGLONG": "long long",
-        "LONG32": "int",
-        "LONG64": "long long",
-        "WORD": "unsigned short",
-        "PVOID": model.voidp_type,
-        "ULONGLONG": "unsigned long long",
-        "WCHAR": "wchar_t",
-        "SHORT": "short",
-        "UCHAR": "unsigned char",
-        "UINT": "unsigned int",
-        "UINT8": "unsigned char",
-        "UINT16": "unsigned short",
-        "UINT32": "unsigned int",
-        "UINT64": "unsigned long long",
-        "ULONG": "unsigned long",
-        "ULONG32": "unsigned int",
-        "ULONG64": "unsigned long long",
-        "USHORT": "unsigned short",
-
-        "SIZE_T": "ULONG_PTR",
-        "SSIZE_T": "LONG_PTR",
-        "ATOM": "WORD",
-        "BOOLEAN": "BYTE",
-        "COLORREF": "DWORD",
-
-        "HANDLE": "PVOID",
-        "DWORDLONG": "ULONGLONG",
-        "DWORD_PTR": "ULONG_PTR",
-        "HACCEL": "HANDLE",
-
-        "HBITMAP": "HANDLE",
-        "HBRUSH": "HANDLE",
-        "HCOLORSPACE": "HANDLE",
-        "HCONV": "HANDLE",
-        "HCONVLIST": "HANDLE",
-        "HDC": "HANDLE",
-        "HDDEDATA": "HANDLE",
-        "HDESK": "HANDLE",
-        "HDROP": "HANDLE",
-        "HDWP": "HANDLE",
-        "HENHMETAFILE": "HANDLE",
-        "HFILE": "int",
-        "HFONT": "HANDLE",
-        "HGDIOBJ": "HANDLE",
-        "HGLOBAL": "HANDLE",
-        "HHOOK": "HANDLE",
-        "HICON": "HANDLE",
-        "HCURSOR": "HICON",
-        "HINSTANCE": "HANDLE",
-        "HKEY": "HANDLE",
-        "HKL": "HANDLE",
-        "HLOCAL": "HANDLE",
-        "HMENU": "HANDLE",
-        "HMETAFILE": "HANDLE",
-        "HMODULE": "HINSTANCE",
-        "HMONITOR": "HANDLE",
-        "HPALETTE": "HANDLE",
-        "HPEN": "HANDLE",
-        "HRESULT": "LONG",
-        "HRGN": "HANDLE",
-        "HRSRC": "HANDLE",
-        "HSZ": "HANDLE",
-        "WINSTA": "HANDLE",
-        "HWND": "HANDLE",
-
-        "LANGID": "WORD",
-        "LCID": "DWORD",
-        "LCTYPE": "DWORD",
-        "LGRPID": "DWORD",
-        "LPARAM": "LONG_PTR",
-        "LPBOOL": "BOOL *",
-        "LPBYTE": "BYTE *",
-        "LPCOLORREF": "DWORD *",
-        "LPCSTR": "const char *",
-
-        "LPCVOID": model.const_voidp_type,
-        "LPCWSTR": "const WCHAR *",
-        "LPDWORD": "DWORD *",
-        "LPHANDLE": "HANDLE *",
-        "LPINT": "int *",
-        "LPLONG": "long *",
-        "LPSTR": "CHAR *",
-        "LPWSTR": "WCHAR *",
-        "LPVOID": model.voidp_type,
-        "LPWORD": "WORD *",
-        "LRESULT": "LONG_PTR",
-        "PBOOL": "BOOL *",
-        "PBOOLEAN": "BOOLEAN *",
-        "PBYTE": "BYTE *",
-        "PCHAR": "CHAR *",
-        "PCSTR": "const CHAR *",
-        "PCWSTR": "const WCHAR *",
-        "PDWORD": "DWORD *",
-        "PDWORDLONG": "DWORDLONG *",
-        "PDWORD_PTR": "DWORD_PTR *",
-        "PDWORD32": "DWORD32 *",
-        "PDWORD64": "DWORD64 *",
-        "PFLOAT": "FLOAT *",
-        "PHALF_PTR": "HALF_PTR *",
-        "PHANDLE": "HANDLE *",
-        "PHKEY": "HKEY *",
-        "PINT": "int *",
-        "PINT_PTR": "INT_PTR *",
-        "PINT8": "INT8 *",
-        "PINT16": "INT16 *",
-        "PINT32": "INT32 *",
-        "PINT64": "INT64 *",
-        "PLCID": "PDWORD",
-        "PLONG": "LONG *",
-        "PLONGLONG": "LONGLONG *",
-        "PLONG_PTR": "LONG_PTR *",
-        "PLONG32": "LONG32 *",
-        "PLONG64": "LONG64 *",
-        "PSHORT": "SHORT *",
-        "PSIZE_T": "SIZE_T *",
-        "PSSIZE_T": "SSIZE_T *",
-        "PSTR": "CHAR *",
-        "PUCHAR": "UCHAR *",
-        "PUHALF_PTR": "UHALF_PTR *",
-        "PUINT": "UINT *",
-        "PUINT_PTR": "UINT_PTR *",
-        "PUINT8": "UINT8 *",
-        "PUINT16": "UINT16 *",
-        "PUINT32": "UINT32 *",
-        "PUINT64": "UINT64 *",
-        "PULONG": "ULONG *",
-        "PULONGLONG": "ULONGLONG *",
-        "PULONG_PTR": "ULONG_PTR *",
-        "PULONG32": "ULONG32 *",
-        "PULONG64": "ULONG64 *",
-        "PUSHORT": "USHORT *",
-        "PWCHAR": "WCHAR *",
-        "PWORD": "WORD *",
-        "PWSTR": "WCHAR *",
-        "QWORD": "unsigned long long",
-        "SC_HANDLE": "HANDLE",
-        "SC_LOCK": "LPVOID",
-        "SERVICE_STATUS_HANDLE": "HANDLE",
-
+def win_common_types():
+    return {
         "UNICODE_STRING": model.StructType(
             "_UNICODE_STRING",
             ["Length",
@@ -232,10 +62,6 @@
         "PUNICODE_STRING": "UNICODE_STRING *",
         "PCUNICODE_STRING": "const UNICODE_STRING *",
 
-        "USN": "LONGLONG",
-        "VOID": model.void_type,
-        "WPARAM": "UINT_PTR",
-
         "TBYTE": "set-unicode-needed",
         "TCHAR": "set-unicode-needed",
         "LPCTSTR": "set-unicode-needed",
@@ -244,9 +70,7 @@
         "PTSTR": "set-unicode-needed",
         "PTBYTE": "set-unicode-needed",
         "PTCHAR": "set-unicode-needed",
-        })
-    return result
-
+        }
 
 if sys.platform == 'win32':
-    COMMON_TYPES.update(win_common_types(sys.maxsize))
+    COMMON_TYPES.update(win_common_types())
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -29,6 +29,8 @@
 _r_stdcall1 = re.compile(r"\b(__stdcall|WINAPI)\b")
 _r_stdcall2 = re.compile(r"[(]\s*(__stdcall|WINAPI)\b")
 _r_cdecl = re.compile(r"\b__cdecl\b")
+_r_star_const_space = re.compile(       # matches "* const "
+    r"[*]\s*((const|volatile|restrict)\b\s*)+")
 
 def _get_parser():
     global _parser_cache
@@ -36,6 +38,46 @@
         _parser_cache = pycparser.CParser()
     return _parser_cache
 
+def _workaround_for_old_pycparser(csource):
+    # Workaround for a pycparser issue (fixed between pycparser 2.10 and
+    # 2.14): "char*const***" gives us a wrong syntax tree, the same as
+    # for "char***(*const)".  This means we can't tell the difference
+    # afterwards.  But "char(*const(***))" gives us the right syntax
+    # tree.  The issue only occurs if there are several stars in
+    # sequence with no parenthesis inbetween, just possibly qualifiers.
+    # Attempt to fix it by adding some parentheses in the source: each
+    # time we see "* const" or "* const *", we add an opening
+    # parenthesis before each star---the hard part is figuring out where
+    # to close them.
+    parts = []
+    while True:
+        match = _r_star_const_space.search(csource)
+        if not match:
+            break
+        #print repr(''.join(parts)+csource), '=>',
+        parts.append(csource[:match.start()])
+        parts.append('('); closing = ')'
+        parts.append(match.group())   # e.g. "* const "
+        endpos = match.end()
+        if csource.startswith('*', endpos):
+            parts.append('('); closing += ')'
+        level = 0
+        for i in xrange(endpos, len(csource)):
+            c = csource[i]
+            if c == '(':
+                level += 1
+            elif c == ')':
+                if level == 0:
+                    break
+                level -= 1
+            elif c in ',;=':
+                if level == 0:
+                    break
+        csource = csource[endpos:i] + closing + csource[i:]
+        #print repr(''.join(parts)+csource)
+    parts.append(csource)
+    return ''.join(parts)
+
 def _preprocess(csource):
     # Remove comments.  NOTE: this only work because the cdef() section
     # should not contain any string literal!
@@ -47,6 +89,10 @@
         macrovalue = macrovalue.replace('\\\n', '').strip()
         macros[macroname] = macrovalue
     csource = _r_define.sub('', csource)
+    #
+    if pycparser.__version__ < '2.14':
+        csource = _workaround_for_old_pycparser(csource)
+    #
     # BIG HACK: replace WINAPI or __stdcall with "volatile const".
     # It doesn't make sense for the return type of a function to be
     # "volatile volatile const", so we abuse it to detect __stdcall...
@@ -320,13 +366,15 @@
                     self._declare('variable ' + decl.name, tp, quals=quals)
 
     def parse_type(self, cdecl):
+        return self.parse_type_and_quals(cdecl)[0]
+
+    def parse_type_and_quals(self, cdecl):
         ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2]
         assert not macros
         exprnode = ast.ext[-1].type.args.params[0]
         if isinstance(exprnode, pycparser.c_ast.ID):
             raise api.CDefError("unknown identifier '%s'" % (exprnode.name,))
-        tp, quals = self._get_type_and_quals(exprnode.type)
-        return tp
+        return self._get_type_and_quals(exprnode.type)
 
     def _declare(self, name, obj, included=False, quals=0):
         if name in self._declarations:
@@ -348,6 +396,8 @@
                              pycparser.c_ast.PtrDecl)):
             if 'const' in type.quals:
                 quals |= model.Q_CONST
+            if 'volatile' in type.quals:
+                quals |= model.Q_VOLATILE
             if 'restrict' in type.quals:
                 quals |= model.Q_RESTRICT
         return quals
@@ -422,7 +472,8 @@
                 if ident == '__dotdotdot__':
                     raise api.FFIError(':%d: bad usage of "..."' %
                             typenode.coord.line)
-                return resolve_common_type(ident), quals
+                tp0, quals0 = resolve_common_type(self, ident)
+                return tp0, (quals | quals0)
             #
             if isinstance(type, pycparser.c_ast.Struct):
                 # 'struct foobar'
@@ -456,6 +507,13 @@
 
     def _parse_function_type(self, typenode, funcname=None):
         params = list(getattr(typenode.args, 'params', []))
+        for i, arg in enumerate(params):
+            if not hasattr(arg, 'type'):
+                raise api.CDefError("%s arg %d: unknown type '%s'"
+                    " (if you meant to use the old C syntax of giving"
+                    " untyped arguments, it is not supported)"
+                    % (funcname or 'in expression', i + 1,
+                       getattr(arg, 'name', '?')))
         ellipsis = (
             len(params) > 0 and
             isinstance(params[-1].type, pycparser.c_ast.TypeDecl) and
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -7,10 +7,13 @@
 # type qualifiers
 Q_CONST    = 0x01
 Q_RESTRICT = 0x02
+Q_VOLATILE = 0x04
 
 def qualify(quals, replace_with):
     if quals & Q_CONST:
         replace_with = ' const ' + replace_with.lstrip()
+    if quals & Q_VOLATILE:
+        replace_with = ' volatile ' + replace_with.lstrip()
     if quals & Q_RESTRICT:
         # It seems that __restrict is supported by gcc and msvc.
         # If you hit some different compiler, add a #define in
diff --git a/lib_pypy/cffi/parse_c_type.h b/lib_pypy/cffi/parse_c_type.h
--- a/lib_pypy/cffi/parse_c_type.h
+++ b/lib_pypy/cffi/parse_c_type.h
@@ -83,6 +83,8 @@
 #define _CFFI__UNKNOWN_FLOAT_PRIM     (-2)
 #define _CFFI__UNKNOWN_LONG_DOUBLE    (-3)
 
+#define _CFFI__IO_FILE_STRUCT         (-1)
+
 
 struct _cffi_global_s {
     const char *name;
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -76,10 +76,10 @@
     if "cppyy" in working_modules:
         working_modules.remove("cppyy")  # depends on ctypes
 
-if sys.platform.startswith("linux"):
-    _mach = os.popen('uname -m', 'r').read().strip()
-    if _mach.startswith('ppc'):
-        working_modules.remove("_continuation")
+#if sys.platform.startswith("linux"):
+#    _mach = os.popen('uname -m', 'r').read().strip()
+#    if _mach.startswith(...):
+#        working_modules.remove("_continuation")
 
 
 module_dependencies = {
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -85,13 +85,16 @@
 _ssl
     libssl
 
+gdbm
+    libgdbm-dev
+
 Make sure to have these libraries (with development headers) installed before
 building PyPy, otherwise the resulting binary will not contain these modules.
 
 On Debian, this is the command to install all build-time dependencies::
 
     apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
-    libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev
+    libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev
 
 For the optional lzma module on PyPy3 you will also need ``liblzma-dev``.
 
diff --git a/pypy/doc/whatsnew-4.0.0.rst b/pypy/doc/whatsnew-4.0.0.rst
--- a/pypy/doc/whatsnew-4.0.0.rst
+++ b/pypy/doc/whatsnew-4.0.0.rst
@@ -6,12 +6,12 @@
 .. startrev: 3a8f5481dab4
 
 .. branch: keys_with_hash
-Improve the performance of dict.update() and a bunch of methods from
+Improve the performance of ``dict.update()`` and a bunch of methods from
 sets, by reusing the hash value stored in one dict when inspecting
 or changing another dict with that key.
 
 .. branch: optresult-unroll 
-A major refactoring of the ResOperations that kills Box. Also rewrote
+A major refactoring of the ``ResOperations`` that kills Box. Also rewrote
 unrolling to enable future enhancements.  Should improve warmup time
 by 20% or so.
 
@@ -24,7 +24,7 @@
 
 .. branch: gc-more-incremental
 Remove a source of non-incremental-ness in the GC: now
-external_malloc() no longer runs gc_step_until() any more. If there
+``external_malloc()`` no longer runs ``gc_step_until()`` any more. If there
 is a currently-running major collection, we do only so many steps
 before returning. This number of steps depends on the size of the
 allocated object. It is controlled by tracking the general progress
@@ -55,7 +55,7 @@
 floats, cf. issue #2148.
 
 .. branch: cffi-stdcall
-Win32: support '__stdcall' in CFFI.
+Win32: support ``__stdcall`` in CFFI.
 
 .. branch: callfamily
 
@@ -67,19 +67,19 @@
 
 .. branch: type_system-cleanup
 
-Remove some remnants of the old ootypesystem vs lltypesystem dichotomy.
+Remove some remnants of the old ``ootypesystem`` vs ``lltypesystem`` dichotomy.
 
 .. branch: cffi-handle-lifetime
 
-ffi.new_handle() returns handles that work more like CPython's: they
+``ffi.new_handle()`` returns handles that work more like CPython's: they
 remain valid as long as the target exists (unlike the previous
-version, where handles become invalid *before* the __del__ is called).
+version, where handles become invalid *before* the ``__del__`` is called).
 
 .. branch: ufunc-casting
 
-allow automatic casting in ufuncs (and frompypyfunc) to cast the
+allow automatic casting in ufuncs (and ``frompypyfunc``) to cast the
 arguments to the allowed function type declarations, fixes various
-failures in linalg cffi functions
+failures in linalg CFFI functions
 
 .. branch: vecopt
 .. branch: vecopt-merge
@@ -94,4 +94,5 @@
 
 .. branch: lazy-fast2locals
 improve the performance of simple trace functions by lazily calling
-fast2locals and locals2fast only if f_locals is actually accessed.
+``fast2locals`` and ``locals2fast`` only if ``f_locals`` is actually accessed.
+
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -8,3 +8,13 @@
 .. branch: 2174-fix-osx-10-11-translation
 
 Use pkg-config to find ssl headers on OS-X
+
+.. branch: Zearin/minor-whatsnewrst-markup-tweaks-edited-o-1446387512092
+
+.. branch: ppc-stacklet
+
+The PPC machines now support the _continuation module (stackless, greenlets)
+
+.. branch: int_0/i-need-this-library-to-build-on-ubuntu-1-1446717626227
+
+Document that libgdbm-dev is required for translation/packaging
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -8,7 +8,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
 from pypy.interpreter.typedef import TypeDef
-from rpython.rlib import jit
+from rpython.rlib import jit, rarithmetic
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rarithmetic import r_uint, intmask
 from rpython.rlib.rbigint import rbigint
@@ -229,10 +229,22 @@
     return min_max(space, __args__, "min")
 
 
+
 class W_Enumerate(W_Root):
-    def __init__(self, w_iter, w_start):
-        self.w_iter = w_iter
-        self.w_index = w_start
+    def __init__(self, space, w_iterable, w_start):
+        from pypy.objspace.std.listobject import W_ListObject
+        w_iter = space.iter(w_iterable)
+        if space.is_w(space.type(w_start), space.w_int):
+            self.index = space.int_w(w_start)
+            self.w_index = None
+            if self.index == 0 and type(w_iterable) is W_ListObject:
+                w_iter = w_iterable
+        else:
+            self.index = -1
+            self.w_index = w_start
+        self.w_iter_or_list = w_iter
+        if self.w_index is not None:
+            assert not type(self.w_iter_or_list) is W_ListObject
 
     def descr___new__(space, w_subtype, w_iterable, w_start=None):
         self = space.allocate_instance(W_Enumerate, w_subtype)
@@ -240,16 +252,42 @@
             w_start = space.wrap(0)
         else:
             w_start = space.index(w_start)
-        self.__init__(space.iter(w_iterable), w_start)
+        self.__init__(space, w_iterable, w_start)
         return space.wrap(self)
 
     def descr___iter__(self, space):
         return space.wrap(self)
 
     def descr_next(self, space):
-        w_item = space.next(self.w_iter)
+        from pypy.objspace.std.listobject import W_ListObject
         w_index = self.w_index
-        self.w_index = space.add(w_index, space.wrap(1))
+        w_iter_or_list = self.w_iter_or_list
+        w_item = None
+        if w_index is None:
+            index = self.index
+            if type(w_iter_or_list) is W_ListObject:
+                try:
+                    w_item = w_iter_or_list.getitem(index)
+                except IndexError:
+                    self.w_iter_or_list = None
+                    raise OperationError(space.w_StopIteration, space.w_None)
+                self.index = index + 1
+            elif w_iter_or_list is None:
+                raise OperationError(space.w_StopIteration, space.w_None)
+            else:
+                try:
+                    newval = rarithmetic.ovfcheck(index + 1)
+                except OverflowError:
+                    w_index = space.wrap(index)
+                    self.w_index = space.add(w_index, space.wrap(1))
+                    self.index = -1
+                else:
+                    self.index = newval
+            w_index = space.wrap(index)
+        else:
+            self.w_index = space.add(w_index, space.wrap(1))
+        if w_item is None:
+            w_item = space.next(self.w_iter_or_list)
         return space.newtuple([w_index, w_item])
 
     def descr___reduce__(self, space):
@@ -257,12 +295,17 @@
         w_mod    = space.getbuiltinmodule('_pickle_support')
         mod      = space.interp_w(MixedModule, w_mod)
         w_new_inst = mod.get('enumerate_new')
-        w_info = space.newtuple([self.w_iter, self.w_index])
+        w_index = self.w_index
+        if w_index is None:
+            w_index = space.wrap(self.index)
+        else:
+            w_index = self.w_index
+        w_info = space.newtuple([self.w_iter_or_list, w_index])
         return space.newtuple([w_new_inst, w_info])
 
 # exported through _pickle_support
 def _make_enumerate(space, w_iter, w_index):
-    return space.wrap(W_Enumerate(w_iter, w_index))
+    return space.wrap(W_Enumerate(space, w_iter, w_index))
 
 W_Enumerate.typedef = TypeDef("enumerate",
     __new__=interp2app(W_Enumerate.descr___new__.im_func),
diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -264,6 +264,7 @@
         raises(StopIteration,x.next)
 
     def test_enumerate(self):
+        import sys
         seq = range(2,4)
         enum = enumerate(seq)
         assert enum.next() == (0, 2)
@@ -274,6 +275,15 @@
         enum = enumerate(range(5), 2)
         assert list(enum) == zip(range(2, 7), range(5))
 
+        enum = enumerate(range(2), 2**100)
+        assert list(enum) == [(2**100, 0), (2**100+1, 1)]
+
+        enum = enumerate(range(2), sys.maxint)
+        assert list(enum) == [(sys.maxint, 0), (sys.maxint+1, 1)]
+
+        raises(TypeError, enumerate, range(2), 5.5)
+
+
     def test_next(self):
         x = iter(['a', 'b', 'c'])
         assert next(x) == 'a'
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -43,6 +43,7 @@
         'newp_handle': 'handle.newp_handle',
         'from_handle': 'handle.from_handle',
         '_get_types': 'func._get_types',
+        '_get_common_types': 'func._get_common_types',
         'from_buffer': 'func.from_buffer',
 
         'string': 'func.string',
diff --git a/pypy/module/_cffi_backend/cffi_opcode.py b/pypy/module/_cffi_backend/cffi_opcode.py
--- a/pypy/module/_cffi_backend/cffi_opcode.py
+++ b/pypy/module/_cffi_backend/cffi_opcode.py
@@ -110,6 +110,9 @@
 _UNKNOWN_FLOAT_PRIM    = -2
 _UNKNOWN_LONG_DOUBLE   = -3
 
+_IO_FILE_STRUCT        = -1
+
+
 PRIMITIVE_TO_INDEX = {
     'char':               PRIM_CHAR,
     'short':              PRIM_SHORT,
diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py
--- a/pypy/module/_cffi_backend/func.py
+++ b/pypy/module/_cffi_backend/func.py
@@ -84,6 +84,20 @@
 
 # ____________________________________________________________
 
+def _get_common_types(space, w_dict):
+    from pypy.module._cffi_backend.parse_c_type import ll_enum_common_types
+    index = 0
+    while True:
+        p = ll_enum_common_types(rffi.cast(rffi.INT, index))
+        if not p:
+            break
+        key = rffi.charp2str(p)
+        value = rffi.charp2str(rffi.ptradd(p, len(key) + 1))
+        space.setitem_str(w_dict, key, space.wrap(value))
+        index += 1
+
+# ____________________________________________________________
+
 def _fetch_as_read_buffer(space, w_x):
     # xxx do we really need to implement the same mess as in CPython 2.7
     # w.r.t. buffers and memoryviews??
diff --git a/pypy/module/_cffi_backend/parse_c_type.py b/pypy/module/_cffi_backend/parse_c_type.py
--- a/pypy/module/_cffi_backend/parse_c_type.py
+++ b/pypy/module/_cffi_backend/parse_c_type.py
@@ -87,6 +87,8 @@
 ll_set_cdl_realize_global_int = llexternal('pypy_set_cdl_realize_global_int',
                                            [lltype.Ptr(GLOBAL_S)],
                                            lltype.Void)
+ll_enum_common_types = llexternal('pypy_enum_common_types',
+                                  [rffi.INT], rffi.CCHARP)
 
 def parse_c_type(info, input):
     p_input = rffi.str2charp(input)
diff --git a/pypy/module/_cffi_backend/realize_c_type.py b/pypy/module/_cffi_backend/realize_c_type.py
--- a/pypy/module/_cffi_backend/realize_c_type.py
+++ b/pypy/module/_cffi_backend/realize_c_type.py
@@ -74,7 +74,15 @@
     assert len(NAMES) == cffi_opcode._NUM_PRIM
 
     def __init__(self, space):
+        self.space = space
         self.all_primitives = [None] * cffi_opcode._NUM_PRIM
+        self.file_struct = None
+
+    def get_file_struct(self):
+        if self.file_struct is None:
+            self.file_struct = ctypestruct.W_CTypeStruct(self.space, "FILE")
+        return self.file_struct
+
 
 def get_primitive_type(ffi, num):
     space = ffi.space
@@ -266,6 +274,10 @@
 
 
 def _realize_c_struct_or_union(ffi, sindex):
+    if sindex == cffi_opcode._IO_FILE_STRUCT:
+        # returns a single global cached opaque type
+        return ffi.space.fromcache(RealizeCache).get_file_struct()
+
     s = ffi.ctxobj.ctx.c_struct_unions[sindex]
     type_index = rffi.getintfield(s, 'c_type_index')
     if ffi.cached_types[type_index] is not None:
@@ -281,7 +293,10 @@
             x = ctypestruct.W_CTypeUnion(space, name)
         else:
             name = _realize_name("struct ", s.c_name)
-            x = ctypestruct.W_CTypeStruct(space, name)
+            if name == "struct _IO_FILE":
+                x = space.fromcache(RealizeCache).get_file_struct()
+            else:
+                x = ctypestruct.W_CTypeStruct(space, name)
         if (c_flags & cffi_opcode.F_OPAQUE) == 0:
             assert c_first_field_index >= 0
             w_ctype = x
diff --git a/pypy/module/_cffi_backend/src/commontypes.c b/pypy/module/_cffi_backend/src/commontypes.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/_cffi_backend/src/commontypes.c
@@ -0,0 +1,207 @@
+/* This file must be kept in alphabetical order.  See test_commontypes.py */
+
+#define EQ(key, value)    key "\0" value   /* string concatenation */
+#ifdef _WIN64
+#  define W32_64(X,Y)  Y
+# else
+#  define W32_64(X,Y)  X
+# endif
+
+
+static const char *common_simple_types[] = {
+
+#ifdef MS_WIN32   /* Windows types */
+    EQ("ATOM", "WORD"),
+    EQ("BOOL", "int"),
+    EQ("BOOLEAN", "BYTE"),
+    EQ("BYTE", "unsigned char"),
+    EQ("CCHAR", "char"),
+    EQ("CHAR", "char"),
+    EQ("COLORREF", "DWORD"),
+    EQ("DWORD", "unsigned long"),
+    EQ("DWORD32", "unsigned int"),
+    EQ("DWORD64", "unsigned long long"),
+    EQ("DWORDLONG", "ULONGLONG"),
+    EQ("DWORD_PTR", "ULONG_PTR"),
+#endif
+
+    EQ("FILE", "struct _IO_FILE"),
+
+#ifdef MS_WIN32   /* more Windows types */
+    EQ("FLOAT", "float"),
+    EQ("HACCEL", "HANDLE"),
+    EQ("HALF_PTR", W32_64("short","int")),
+    EQ("HANDLE", "PVOID"),
+    EQ("HBITMAP", "HANDLE"),
+    EQ("HBRUSH", "HANDLE"),
+    EQ("HCOLORSPACE", "HANDLE"),
+    EQ("HCONV", "HANDLE"),
+    EQ("HCONVLIST", "HANDLE"),
+    EQ("HCURSOR", "HICON"),
+    EQ("HDC", "HANDLE"),
+    EQ("HDDEDATA", "HANDLE"),
+    EQ("HDESK", "HANDLE"),
+    EQ("HDROP", "HANDLE"),
+    EQ("HDWP", "HANDLE"),
+    EQ("HENHMETAFILE", "HANDLE"),
+    EQ("HFILE", "int"),
+    EQ("HFONT", "HANDLE"),
+    EQ("HGDIOBJ", "HANDLE"),
+    EQ("HGLOBAL", "HANDLE"),
+    EQ("HHOOK", "HANDLE"),
+    EQ("HICON", "HANDLE"),
+    EQ("HINSTANCE", "HANDLE"),
+    EQ("HKEY", "HANDLE"),
+    EQ("HKL", "HANDLE"),
+    EQ("HLOCAL", "HANDLE"),
+    EQ("HMENU", "HANDLE"),
+    EQ("HMETAFILE", "HANDLE"),
+    EQ("HMODULE", "HINSTANCE"),
+    EQ("HMONITOR", "HANDLE"),
+    EQ("HPALETTE", "HANDLE"),
+    EQ("HPEN", "HANDLE"),
+    EQ("HRESULT", "LONG"),
+    EQ("HRGN", "HANDLE"),
+    EQ("HRSRC", "HANDLE"),
+    EQ("HSZ", "HANDLE"),
+    EQ("HWND", "HANDLE"),
+    EQ("INT", "int"),
+    EQ("INT16", "short"),
+    EQ("INT32", "int"),
+    EQ("INT64", "long long"),
+    EQ("INT8", "signed char"),
+    EQ("INT_PTR", W32_64("int","long long")),
+    EQ("LANGID", "WORD"),
+    EQ("LCID", "DWORD"),
+    EQ("LCTYPE", "DWORD"),
+    EQ("LGRPID", "DWORD"),
+    EQ("LONG", "long"),
+    EQ("LONG32", "int"),
+    EQ("LONG64", "long long"),
+    EQ("LONGLONG", "long long"),
+    EQ("LONG_PTR", W32_64("long","long long")),
+    EQ("LPARAM", "LONG_PTR"),
+    EQ("LPBOOL", "BOOL *"),
+    EQ("LPBYTE", "BYTE *"),
+    EQ("LPCOLORREF", "DWORD *"),
+    EQ("LPCSTR", "const char *"),
+    EQ("LPCVOID", "const void *"),
+    EQ("LPCWSTR", "const WCHAR *"),
+    EQ("LPDWORD", "DWORD *"),
+    EQ("LPHANDLE", "HANDLE *"),
+    EQ("LPINT", "int *"),
+    EQ("LPLONG", "long *"),
+    EQ("LPSTR", "CHAR *"),
+    EQ("LPVOID", "void *"),
+    EQ("LPWORD", "WORD *"),
+    EQ("LPWSTR", "WCHAR *"),
+    EQ("LRESULT", "LONG_PTR"),
+    EQ("PBOOL", "BOOL *"),
+    EQ("PBOOLEAN", "BOOLEAN *"),
+    EQ("PBYTE", "BYTE *"),
+    EQ("PCHAR", "CHAR *"),
+    EQ("PCSTR", "const CHAR *"),
+    EQ("PCWSTR", "const WCHAR *"),
+    EQ("PDWORD", "DWORD *"),
+    EQ("PDWORD32", "DWORD32 *"),
+    EQ("PDWORD64", "DWORD64 *"),
+    EQ("PDWORDLONG", "DWORDLONG *"),
+    EQ("PDWORD_PTR", "DWORD_PTR *"),
+    EQ("PFLOAT", "FLOAT *"),
+    EQ("PHALF_PTR", "HALF_PTR *"),
+    EQ("PHANDLE", "HANDLE *"),
+    EQ("PHKEY", "HKEY *"),
+    EQ("PINT", "int *"),
+    EQ("PINT16", "INT16 *"),
+    EQ("PINT32", "INT32 *"),
+    EQ("PINT64", "INT64 *"),
+    EQ("PINT8", "INT8 *"),
+    EQ("PINT_PTR", "INT_PTR *"),
+    EQ("PLCID", "PDWORD"),
+    EQ("PLONG", "LONG *"),
+    EQ("PLONG32", "LONG32 *"),
+    EQ("PLONG64", "LONG64 *"),
+    EQ("PLONGLONG", "LONGLONG *"),
+    EQ("PLONG_PTR", "LONG_PTR *"),
+    EQ("PSHORT", "SHORT *"),
+    EQ("PSIZE_T", "SIZE_T *"),
+    EQ("PSSIZE_T", "SSIZE_T *"),
+    EQ("PSTR", "CHAR *"),
+    EQ("PUCHAR", "UCHAR *"),
+    EQ("PUHALF_PTR", "UHALF_PTR *"),
+    EQ("PUINT", "UINT *"),
+    EQ("PUINT16", "UINT16 *"),
+    EQ("PUINT32", "UINT32 *"),
+    EQ("PUINT64", "UINT64 *"),
+    EQ("PUINT8", "UINT8 *"),
+    EQ("PUINT_PTR", "UINT_PTR *"),
+    EQ("PULONG", "ULONG *"),
+    EQ("PULONG32", "ULONG32 *"),
+    EQ("PULONG64", "ULONG64 *"),
+    EQ("PULONGLONG", "ULONGLONG *"),
+    EQ("PULONG_PTR", "ULONG_PTR *"),
+    EQ("PUSHORT", "USHORT *"),
+    EQ("PVOID", "void *"),
+    EQ("PWCHAR", "WCHAR *"),
+    EQ("PWORD", "WORD *"),
+    EQ("PWSTR", "WCHAR *"),
+    EQ("QWORD", "unsigned long long"),
+    EQ("SC_HANDLE", "HANDLE"),
+    EQ("SC_LOCK", "LPVOID"),
+    EQ("SERVICE_STATUS_HANDLE", "HANDLE"),
+    EQ("SHORT", "short"),
+    EQ("SIZE_T", "ULONG_PTR"),
+    EQ("SSIZE_T", "LONG_PTR"),
+    EQ("UCHAR", "unsigned char"),
+    EQ("UHALF_PTR", W32_64("unsigned short","unsigned int")),
+    EQ("UINT", "unsigned int"),
+    EQ("UINT16", "unsigned short"),
+    EQ("UINT32", "unsigned int"),
+    EQ("UINT64", "unsigned long long"),
+    EQ("UINT8", "unsigned char"),
+    EQ("UINT_PTR", W32_64("unsigned int","unsigned long long")),
+    EQ("ULONG", "unsigned long"),
+    EQ("ULONG32", "unsigned int"),
+    EQ("ULONG64", "unsigned long long"),
+    EQ("ULONGLONG", "unsigned long long"),
+    EQ("ULONG_PTR", W32_64("unsigned long","unsigned long long")),
+    EQ("USHORT", "unsigned short"),
+    EQ("USN", "LONGLONG"),
+    EQ("VOID", "void"),
+    EQ("WCHAR", "wchar_t"),
+    EQ("WINSTA", "HANDLE"),
+    EQ("WORD", "unsigned short"),
+    EQ("WPARAM", "UINT_PTR"),
+#endif
+
+    EQ("bool", "_Bool"),
+};
+
+
+#undef EQ
+#undef W32_64
+
+#define num_common_simple_types    \
+    (sizeof(common_simple_types) / sizeof(common_simple_types[0]))
+
+
+static const char *get_common_type(const char *search, size_t search_len)
+{
+    const char *entry;
+    int index = search_sorted(common_simple_types, sizeof(const char *),
+                              num_common_simple_types, search, search_len);
+    if (index < 0)
+        return NULL;
+
+    entry = common_simple_types[index];
+    return entry + strlen(entry) + 1;
+}
+
+RPY_EXTERN
+char *pypy_enum_common_types(int index)
+{
+    if (index < num_common_simple_types)
+        return (char *)(common_simple_types[index]);
+    else
+        return NULL;
+}
diff --git a/pypy/module/_cffi_backend/src/parse_c_type.c b/pypy/module/_cffi_backend/src/parse_c_type.c
--- a/pypy/module/_cffi_backend/src/parse_c_type.c
+++ b/pypy/module/_cffi_backend/src/parse_c_type.c
@@ -231,6 +231,8 @@
 #define MAX_SSIZE_T  (((size_t)-1) >> 1)
 
 static int parse_complete(token_t *tok);
+static const char *get_common_type(const char *search, size_t search_len);
+static int parse_common_type_replacement(token_t *tok, const char *replacement);
 
 static int parse_sequel(token_t *tok, int outer)
 {
@@ -387,11 +389,18 @@
 
             case TOK_INTEGER:
                 errno = 0;
-#ifndef _MSC_VER
-                if (sizeof(length) > sizeof(unsigned long))
+                if (sizeof(length) > sizeof(unsigned long)) {
+#ifdef MS_WIN32
+# ifdef _WIN64
+                    length = _strtoui64(tok->p, &endptr, 0);
+# else
+                    abort();  /* unreachable */
+# endif
+#else
                     length = strtoull(tok->p, &endptr, 0);
+#endif
+                }
                 else
-#endif
                     length = strtoul(tok->p, &endptr, 0);
                 if (endptr != tok->p + tok->size)
                     return parse_error(tok, "invalid number");
@@ -446,26 +455,34 @@
     return _CFFI_GETARG(result);
 }
 
+static int search_sorted(const char *const *base,
+                         size_t item_size, int array_len,
+                         const char *search, size_t search_len)
+{
+    int left = 0, right = array_len;
+    const char *baseptr = (const char *)base;
 
-#define MAKE_SEARCH_FUNC(FIELD)                                 \
-  RPY_EXTERN int                                                \
-  pypy_search_in_##FIELD(const struct _cffi_type_context_s *ctx,\
-                        const char *search, size_t search_len)  \
-  {                                                             \
-      int left = 0, right = ctx->num_##FIELD;                   \
-                                                                \
-      while (left < right) {                                    \
-          int middle = (left + right) / 2;                      \
-          const char *src = ctx->FIELD[middle].name;            \
-          int diff = strncmp(src, search, search_len);          \
-          if (diff == 0 && src[search_len] == '\0')             \
-              return middle;                                    \
-          else if (diff >= 0)                                   \
-              right = middle;                                   \
-          else                                                  \
-              left = middle + 1;                                \
-      }                                                         \
-      return -1;                                                \
+    while (left < right) {
+        int middle = (left + right) / 2;
+        const char *src = *(const char *const *)(baseptr + middle * item_size);
+        int diff = strncmp(src, search, search_len);
+        if (diff == 0 && src[search_len] == '\0')
+            return middle;
+        else if (diff >= 0)
+            right = middle;
+        else
+            left = middle + 1;
+    }
+    return -1;
+}
+
+#define MAKE_SEARCH_FUNC(FIELD)                                         \
+  RPY_EXTERN int                                                        \
+  pypy_search_in_##FIELD(const struct _cffi_type_context_s *ctx,        \
+                        const char *search, size_t search_len)          \
+  {                                                                     \
+      return search_sorted(&ctx->FIELD->name, sizeof(*ctx->FIELD),      \
+                           ctx->num_##FIELD, search, search_len);       \
   }
 
 MAKE_SEARCH_FUNC(globals)
@@ -719,6 +736,7 @@
             break;
         case TOK_IDENTIFIER:
         {
+            const char *replacement;
             int n = search_in_typenames(tok->info->ctx, tok->p, tok->size);
             if (n >= 0) {
                 t1 = _CFFI_OP(_CFFI_OP_TYPENAME, n);
@@ -729,6 +747,14 @@
                 t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, n);
                 break;
             }
+            replacement = get_common_type(tok->p, tok->size);
+            if (replacement != NULL) {
+                n = parse_common_type_replacement(tok, replacement);
+                if (n < 0)
+                    return parse_error(tok, "internal error, please report!");
+                t1 = _CFFI_OP(_CFFI_OP_NOOP, n);
+                break;
+            }
             return parse_error(tok, "undefined type name");
         }
         case TOK_STRUCT:
@@ -740,10 +766,15 @@
                 return parse_error(tok, "struct or union name expected");
 
             n = search_in_struct_unions(tok->info->ctx, tok->p, tok->size);
-            if (n < 0)
-                return parse_error(tok, "undefined struct/union name");
-            if (((tok->info->ctx->struct_unions[n].flags & _CFFI_F_UNION) != 0)
-                ^ (kind == TOK_UNION))
+            if (n < 0) {
+                if (kind == TOK_STRUCT && tok->size == 8 &&
+                        !memcmp(tok->p, "_IO_FILE", 8))
+                    n = _CFFI__IO_FILE_STRUCT;
+                else
+                    return parse_error(tok, "undefined struct/union name");
+            }
+            else if (((tok->info->ctx->struct_unions[n].flags & _CFFI_F_UNION)
+                      != 0) ^ (kind == TOK_UNION))
                 return parse_error(tok, "wrong kind of tag: struct vs union");
 
             t1 = _CFFI_OP(_CFFI_OP_STRUCT_UNION, n);
@@ -773,8 +804,9 @@
 }
 
 
-RPY_EXTERN
-int pypy_parse_c_type(struct _cffi_parse_info_s *info, const char *input)
+static
+int parse_c_type_from(struct _cffi_parse_info_s *info, size_t *output_index,
+                      const char *input)
 {
     int result;
     token_t token;
@@ -785,16 +817,33 @@
     token.p = input;
     token.size = 0;
     token.output = info->output;
-    token.output_index = 0;
+    token.output_index = *output_index;
 
     next_token(&token);
     result = parse_complete(&token);
 
+    *output_index = token.output_index;
     if (token.kind != TOK_END)
         return parse_error(&token, "unexpected symbol");
     return result;
 }
 
+RPY_EXTERN
+int pypy_parse_c_type(struct _cffi_parse_info_s *info, const char *input)
+{
+    size_t output_index = 0;
+    return parse_c_type_from(info, &output_index, input);
+}
+
+static
+int parse_common_type_replacement(token_t *tok, const char *replacement)
+{
+    return parse_c_type_from(tok->info, &tok->output_index, replacement);
+}
+
+
+#include "commontypes.c"      /* laziness hack: include this file here */
+
 
 /************************************************************/
 /* extra from cdlopen.c                                     */
diff --git a/pypy/module/_cffi_backend/src/parse_c_type.h b/pypy/module/_cffi_backend/src/parse_c_type.h
--- a/pypy/module/_cffi_backend/src/parse_c_type.h
+++ b/pypy/module/_cffi_backend/src/parse_c_type.h
@@ -5,7 +5,7 @@
 
 #define _CFFI_OP(opcode, arg)   (_cffi_opcode_t)(opcode | (((uintptr_t)(arg)) << 8))
 #define _CFFI_GETOP(cffi_opcode)    ((unsigned char)(uintptr_t)cffi_opcode)
-#define _CFFI_GETARG(cffi_opcode)   (((uintptr_t)cffi_opcode) >> 8)
+#define _CFFI_GETARG(cffi_opcode)   (((intptr_t)cffi_opcode) >> 8)
 
 #define _CFFI_OP_PRIMITIVE       1
 #define _CFFI_OP_POINTER         3
@@ -25,6 +25,8 @@
 #define _CFFI_OP_CONSTANT_INT   31
 #define _CFFI_OP_GLOBAL_VAR     33
 #define _CFFI_OP_DLOPEN_FUNC    35
+#define _CFFI_OP_DLOPEN_CONST   37
+#define _CFFI_OP_GLOBAL_VAR_F   39
 
 #define _CFFI_PRIM_VOID          0
 #define _CFFI_PRIM_BOOL          1
@@ -77,6 +79,11 @@
 #define _CFFI_PRIM_UINTMAX      47
 
 #define _CFFI__NUM_PRIM         48
+#define _CFFI__UNKNOWN_PRIM           (-1)
+#define _CFFI__UNKNOWN_FLOAT_PRIM     (-2)
+#define _CFFI__UNKNOWN_LONG_DOUBLE    (-3)
+
+#define _CFFI__IO_FILE_STRUCT         (-1)
 
 
 struct _cffi_global_s {
@@ -164,4 +171,6 @@
                              const char *search, size_t search_len);
 RPY_EXTERN
 void pypy_set_cdl_realize_global_int(struct _cffi_global_s *target);
+RPY_EXTERN
+char *pypy_enum_common_types(int index);
 #endif
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -3509,3 +3509,8 @@
         assert repr(BFunc) == "<ctype 'int(__stdcall *)(int, int)'>"
     else:
         assert repr(BFunc) == "<ctype 'int(*)(int, int)'>"
+
+def test_get_common_types():
+    d = {}
+    _get_common_types(d)
+    assert d['bool'] == '_Bool'
diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py b/pypy/module/_cffi_backend/test/test_ffi_obj.py
--- a/pypy/module/_cffi_backend/test/test_ffi_obj.py
+++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py
@@ -424,3 +424,26 @@
             return ffi.NULL
         alloc5 = ffi.new_allocator(myalloc5)
         raises(MemoryError, alloc5, "int[5]")
+
+    def test_bool_issue228(self):
+        import _cffi_backend as _cffi1_backend
+        ffi = _cffi1_backend.FFI()
+        fntype = ffi.typeof("int(*callback)(bool is_valid)")
+        assert repr(fntype.args[0]) == "<ctype '_Bool'>"
+
+    def test_FILE_issue228(self):
+        import _cffi_backend as _cffi1_backend
+        fntype1 = _cffi1_backend.FFI().typeof("FILE *")
+        fntype2 = _cffi1_backend.FFI().typeof("FILE *")
+        assert repr(fntype1) == "<ctype 'FILE *'>"
+        assert fntype1 is fntype2
+
+    def test_cast_from_int_type_to_bool(self):
+        import _cffi_backend as _cffi1_backend
+        ffi = _cffi1_backend.FFI()
+        for basetype in ['char', 'short', 'int', 'long', 'long long']:
+            for sign in ['signed', 'unsigned']:
+                type = '%s %s' % (sign, basetype)
+                assert int(ffi.cast("_Bool", ffi.cast(type, 42))) == 1
+                assert int(ffi.cast("bool", ffi.cast(type, 42))) == 1
+                assert int(ffi.cast("_Bool", ffi.cast(type, 0))) == 0
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -28,6 +28,7 @@
     module_name = '_CFFI_' + module_name
     rdir = udir.ensure('recompiler', dir=1)
     rdir.join('Python.h').write(
+        '#include <stdio.h>\n'
         '#define PYPY_VERSION XX\n'
         '#define PyMODINIT_FUNC /*exported*/ void\n'
         )
@@ -1076,3 +1077,302 @@
         raises(ffi.error, getattr, lib, 'my_value')
         e = raises(ffi.error, setattr, lib, 'my_value', 50)
         assert str(e.value) == "global variable 'my_value' is at address NULL"
+
+    def test_const_fields(self):
+        ffi, lib = self.prepare(
+            """struct foo_s { const int a; void *const b; };""",
+            'test_const_fields',
+            """struct foo_s { const int a; void *const b; };""")
+        foo_s = ffi.typeof("struct foo_s")
+        assert foo_s.fields[0][0] == 'a'
+        assert foo_s.fields[0][1].type is ffi.typeof("int")
+        assert foo_s.fields[1][0] == 'b'
+        assert foo_s.fields[1][1].type is ffi.typeof("void *")
+
+    def test_restrict_fields(self):
+        ffi, lib = self.prepare(
+            """struct foo_s { void * restrict b; };""",
+            'test_restrict_fields',
+            """struct foo_s { void * __restrict b; };""")
+        foo_s = ffi.typeof("struct foo_s")
+        assert foo_s.fields[0][0] == 'b'
+        assert foo_s.fields[0][1].type is ffi.typeof("void *")
+
+    def test_volatile_fields(self):
+        ffi, lib = self.prepare(
+            """struct foo_s { void * volatile b; };""",
+            'test_volatile_fields',
+            """struct foo_s { void * volatile b; };""")
+        foo_s = ffi.typeof("struct foo_s")
+        assert foo_s.fields[0][0] == 'b'
+        assert foo_s.fields[0][1].type is ffi.typeof("void *")
+
+    def test_const_array_fields(self):
+        ffi, lib = self.prepare(
+            """struct foo_s { const int a[4]; };""",
+            'test_const_array_fields',
+            """struct foo_s { const int a[4]; };""")
+        foo_s = ffi.typeof("struct foo_s")
+        assert foo_s.fields[0][0] == 'a'
+        assert foo_s.fields[0][1].type is ffi.typeof("int[4]")
+
+    def test_const_array_fields_varlength(self):
+        ffi, lib = self.prepare(
+            """struct foo_s { const int a[]; ...; };""",
+            'test_const_array_fields_varlength',
+            """struct foo_s { const int a[4]; };""")
+        foo_s = ffi.typeof("struct foo_s")
+        assert foo_s.fields[0][0] == 'a'
+        assert foo_s.fields[0][1].type is ffi.typeof("int[]")
+
+    def test_const_array_fields_unknownlength(self):
+        ffi, lb = self.prepare(
+            """struct foo_s { const int a[...]; ...; };""",
+            'test_const_array_fields_unknownlength',
+            """struct foo_s { const int a[4]; };""")
+        foo_s = ffi.typeof("struct foo_s")
+        assert foo_s.fields[0][0] == 'a'
+        assert foo_s.fields[0][1].type is ffi.typeof("int[4]")
+
+    def test_const_function_args(self):
+        ffi, lib = self.prepare(
+            """int foobar(const int a, const int *b, const int c[]);""",
+            'test_const_function_args', """
+            int foobar(const int a, const int *b, const int c[]) {
+                return a + *b + *c;
+            }
+        """)
+        assert lib.foobar(100, ffi.new("int *", 40), ffi.new("int *", 2)) == 142
+
+    def test_const_function_type_args(self):
+        ffi, lib = self.prepare(
+            """int (*foobar)(const int a, const int *b, const int c[]);""",
+            'test_const_function_type_args', """
+            int (*foobar)(const int a, const int *b, const int c[]);
+        """)
+        t = ffi.typeof(lib.foobar)
+        assert t.args[0] is ffi.typeof("int")
+        assert t.args[1] is ffi.typeof("int *")
+        assert t.args[2] is ffi.typeof("int *")
+
+    def test_const_constant(self):
+        ffi, lib = self.prepare(
+            """struct foo_s { int x,y; }; const struct foo_s myfoo;""",
+            'test_const_constant', """
+            struct foo_s { int x,y; }; const struct foo_s myfoo = { 40, 2 };
+        """)
+        assert lib.myfoo.x == 40
+        assert lib.myfoo.y == 2
+
+    def test_const_via_typedef(self):
+        ffi, lib = self.prepare(
+            """typedef const int const_t; const_t aaa;""",
+            'test_const_via_typedef', """
+            typedef const int const_t;
+            #define aaa 42
+        """)
+        assert lib.aaa == 42
+        raises(AttributeError, "lib.aaa = 43")
+
+    def test_win32_calling_convention_0(self):
+        import sys
+        ffi, lib = self.prepare(
+            """
+            int call1(int(__cdecl   *cb)(int));
+            int (*const call2)(int(__stdcall *cb)(int));
+            """,
+            'test_win32_calling_convention_0', r"""
+            #ifndef _MSC_VER
+            #  define __stdcall  /* nothing */
+            #endif
+            int call1(int(*cb)(int)) {
+                int i, result = 0;
+                //printf("call1: cb = %p\n", cb);
+                for (i = 0; i < 1000; i++)
+                    result += cb(i);
+                //printf("result = %d\n", result);
+                return result;
+            }
+            int call2(int(__stdcall *cb)(int)) {
+                int i, result = 0;
+                //printf("call2: cb = %p\n", cb);
+                for (i = 0; i < 1000; i++)
+                    result += cb(-i);
+                //printf("result = %d\n", result);
+                return result;
+            }
+        """)
+        @ffi.callback("int(int)")
+        def cb1(x):
+            return x * 2
+        @ffi.callback("int __stdcall(int)")
+        def cb2(x):
+            return x * 3
+        res = lib.call1(cb1)
+        assert res == 500*999*2
+        assert res == ffi.addressof(lib, 'call1')(cb1)
+        res = lib.call2(cb2)
+        assert res == -500*999*3
+        assert res == ffi.addressof(lib, 'call2')(cb2)
+        if sys.platform == 'win32' and not sys.maxsize > 2**32:
+            assert '__stdcall' in str(ffi.typeof(cb2))
+            assert '__stdcall' not in str(ffi.typeof(cb1))
+            raises(TypeError, lib.call1, cb2)
+            raises(TypeError, lib.call2, cb1)
+        else:
+            assert '__stdcall' not in str(ffi.typeof(cb2))
+            assert ffi.typeof(cb2) is ffi.typeof(cb1)
+
+    def test_win32_calling_convention_1(self):
+        ffi, lib = self.prepare("""
+            int __cdecl   call1(int(__cdecl   *cb)(int));
+            int __stdcall call2(int(__stdcall *cb)(int));
+            int (__cdecl   *const cb1)(int);
+            int (__stdcall *const cb2)(int);
+        """, 'test_win32_calling_convention_1', r"""
+            #ifndef _MSC_VER
+            #  define __cdecl
+            #  define __stdcall
+            #endif
+            int __cdecl   cb1(int x) { return x * 2; }
+            int __stdcall cb2(int x) { return x * 3; }
+
+            int __cdecl call1(int(__cdecl *cb)(int)) {
+                int i, result = 0;
+                //printf("here1\n");
+                //printf("cb = %p, cb1 = %p\n", cb, (void *)cb1);
+                for (i = 0; i < 1000; i++)
+                    result += cb(i);
+                //printf("result = %d\n", result);
+                return result;
+            }
+            int __stdcall call2(int(__stdcall *cb)(int)) {
+                int i, result = 0;
+                //printf("here1\n");
+                //printf("cb = %p, cb2 = %p\n", cb, (void *)cb2);
+                for (i = 0; i < 1000; i++)
+                    result += cb(-i);
+                //printf("result = %d\n", result);
+                return result;
+            }
+        """)
+        #print '<<< cb1 =', ffi.addressof(lib, 'cb1')
+        ptr_call1 = ffi.addressof(lib, 'call1')
+        assert lib.call1(ffi.addressof(lib, 'cb1')) == 500*999*2
+        assert ptr_call1(ffi.addressof(lib, 'cb1')) == 500*999*2
+        #print '<<< cb2 =', ffi.addressof(lib, 'cb2')
+        ptr_call2 = ffi.addressof(lib, 'call2')
+        assert lib.call2(ffi.addressof(lib, 'cb2')) == -500*999*3
+        assert ptr_call2(ffi.addressof(lib, 'cb2')) == -500*999*3
+        #print '<<< done'
+
+    def test_win32_calling_convention_2(self):
+        import sys
+        # any mistake in the declaration of plain function (including the
+        # precise argument types and, here, the calling convention) are
+        # automatically corrected.  But this does not apply to the 'cb'
+        # function pointer argument.
+        ffi, lib = self.prepare("""
+            int __stdcall call1(int(__cdecl   *cb)(int));
+            int __cdecl   call2(int(__stdcall *cb)(int));
+            int (__cdecl   *const cb1)(int);
+            int (__stdcall *const cb2)(int);
+        """, 'test_win32_calling_convention_2', """
+            #ifndef _MSC_VER
+            #  define __cdecl
+            #  define __stdcall
+            #endif
+            int __cdecl call1(int(__cdecl *cb)(int)) {
+                int i, result = 0;
+                for (i = 0; i < 1000; i++)
+                    result += cb(i);
+                return result;
+            }
+            int __stdcall call2(int(__stdcall *cb)(int)) {
+                int i, result = 0;
+                for (i = 0; i < 1000; i++)
+                    result += cb(-i);
+                return result;
+            }
+            int __cdecl   cb1(int x) { return x * 2; }
+            int __stdcall cb2(int x) { return x * 3; }
+        """)
+        ptr_call1 = ffi.addressof(lib, 'call1')
+        ptr_call2 = ffi.addressof(lib, 'call2')
+        if sys.platform == 'win32' and not sys.maxsize > 2**32:
+            raises(TypeError, lib.call1, ffi.addressof(lib, 'cb2'))
+            raises(TypeError, ptr_call1, ffi.addressof(lib, 'cb2'))
+            raises(TypeError, lib.call2, ffi.addressof(lib, 'cb1'))
+            raises(TypeError, ptr_call2, ffi.addressof(lib, 'cb1'))
+        assert lib.call1(ffi.addressof(lib, 'cb1')) == 500*999*2
+        assert ptr_call1(ffi.addressof(lib, 'cb1')) == 500*999*2
+        assert lib.call2(ffi.addressof(lib, 'cb2')) == -500*999*3
+        assert ptr_call2(ffi.addressof(lib, 'cb2')) == -500*999*3
+
+    def test_win32_calling_convention_3(self):
+        import sys
+        ffi, lib = self.prepare("""
+            struct point { int x, y; };
+
+            int (*const cb1)(struct point);
+            int (__stdcall *const cb2)(struct point);
+
+            struct point __stdcall call1(int(*cb)(struct point));
+            struct point call2(int(__stdcall *cb)(struct point));
+        """, 'test_win32_calling_convention_3', r"""
+            #ifndef _MSC_VER
+            #  define __cdecl
+            #  define __stdcall
+            #endif
+            struct point { int x, y; };
+            int           cb1(struct point pt) { return pt.x + 10 * pt.y; }
+            int __stdcall cb2(struct point pt) { return pt.x + 100 * pt.y; }
+            struct point __stdcall call1(int(__cdecl *cb)(struct point)) {
+                int i;
+                struct point result = { 0, 0 };
+                //printf("here1\n");
+                //printf("cb = %p, cb1 = %p\n", cb, (void *)cb1);
+                for (i = 0; i < 1000; i++) {
+                    struct point p = { i, -i };
+                    int r = cb(p);
+                    result.x += r;
+                    result.y -= r;
+                }
+                return result;
+            }
+            struct point __cdecl call2(int(__stdcall *cb)(struct point)) {
+                int i;
+                struct point result = { 0, 0 };
+                for (i = 0; i < 1000; i++) {
+                    struct point p = { -i, i };
+                    int r = cb(p);
+                    result.x += r;
+                    result.y -= r;
+                }
+                return result;
+            }
+        """)
+        ptr_call1 = ffi.addressof(lib, 'call1')
+        ptr_call2 = ffi.addressof(lib, 'call2')
+        if sys.platform == 'win32' and not sys.maxsize > 2**32:
+            raises(TypeError, lib.call1, ffi.addressof(lib, 'cb2'))
+            raises(TypeError, ptr_call1, ffi.addressof(lib, 'cb2'))
+            raises(TypeError, lib.call2, ffi.addressof(lib, 'cb1'))
+            raises(TypeError, ptr_call2, ffi.addressof(lib, 'cb1'))
+        pt = lib.call1(ffi.addressof(lib, 'cb1'))
+        assert (pt.x, pt.y) == (-9*500*999, 9*500*999)
+        pt = ptr_call1(ffi.addressof(lib, 'cb1'))
+        assert (pt.x, pt.y) == (-9*500*999, 9*500*999)
+        pt = lib.call2(ffi.addressof(lib, 'cb2'))
+        assert (pt.x, pt.y) == (99*500*999, -99*500*999)
+        pt = ptr_call2(ffi.addressof(lib, 'cb2'))
+        assert (pt.x, pt.y) == (99*500*999, -99*500*999)
+
+    def test_share_FILE(self):
+        ffi1, lib1 = self.prepare("void do_stuff(FILE *);",
+                                  'test_share_FILE_a',
+                                  "void do_stuff(FILE *f) { (void)f; }")
+        ffi2, lib2 = self.prepare("FILE *barize(void);",
+                                  'test_share_FILE_b',
+                                  "FILE *barize(void) { return NULL; }")
+        lib1.do_stuff(lib2.barize())
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -1,4 +1,4 @@
-from rpython.rlib import rpoll, rsocket, rthread, rweakref
+from rpython.rlib import rpoll, rsocket, rthread, rweakref, rgc
 from rpython.rlib.rarithmetic import intmask, widen, r_uint
 from rpython.rlib.ropenssl import *
 from pypy.module._socket import interp_socket
@@ -852,55 +852,58 @@
                     names = rffi.cast(GENERAL_NAMES, method[0].c_d2i(
                         null, p_ptr, length))
 
-            for j in range(libssl_sk_GENERAL_NAME_num(names)):
-                # Get a rendering of each name in the set of names
+            try:
+                for j in range(libssl_sk_GENERAL_NAME_num(names)):
+                    # Get a rendering of each name in the set of names
 
-                name = libssl_sk_GENERAL_NAME_value(names, j)
-                gntype = intmask(name.c_type)
-                if gntype == GEN_DIRNAME:
-                    # we special-case DirName as a tuple of tuples of
-                    # attributes
-                    dirname = libssl_pypy_GENERAL_NAME_dirn(name)
-                    w_t = space.newtuple([
-                        space.wrap("DirName"),
-                        _create_tuple_for_X509_NAME(space, dirname)
-                        ])
-                elif gntype in (GEN_EMAIL, GEN_DNS, GEN_URI):
-                    # GENERAL_NAME_print() doesn't handle NULL bytes in
-                    # ASN1_string correctly, CVE-2013-4238
-                    if gntype == GEN_EMAIL:
-                        v = space.wrap("email")
-                    elif gntype == GEN_DNS:
-                        v = space.wrap("DNS")
-                    elif gntype == GEN_URI:
-                        v = space.wrap("URI")
+                    name = libssl_sk_GENERAL_NAME_value(names, j)
+                    gntype = intmask(name.c_type)
+                    if gntype == GEN_DIRNAME:
+                        # we special-case DirName as a tuple of tuples of
+                        # attributes
+                        dirname = libssl_pypy_GENERAL_NAME_dirn(name)
+                        w_t = space.newtuple([
+                            space.wrap("DirName"),
+                            _create_tuple_for_X509_NAME(space, dirname)
+                            ])
+                    elif gntype in (GEN_EMAIL, GEN_DNS, GEN_URI):
+                        # GENERAL_NAME_print() doesn't handle NULL bytes in
+                        # ASN1_string correctly, CVE-2013-4238
+                        if gntype == GEN_EMAIL:
+                            v = space.wrap("email")
+                        elif gntype == GEN_DNS:
+                            v = space.wrap("DNS")
+                        elif gntype == GEN_URI:
+                            v = space.wrap("URI")
+                        else:
+                            assert False
+                        as_ = libssl_pypy_GENERAL_NAME_dirn(name)
+                        as_ = rffi.cast(ASN1_STRING, as_)
+                        buf = libssl_ASN1_STRING_data(as_)
+                        length = libssl_ASN1_STRING_length(as_)
+                        w_t = space.newtuple([
+                            v, space.wrap(rffi.charpsize2str(buf, length))])
                     else:
-                        assert False
-                    as_ = libssl_pypy_GENERAL_NAME_dirn(name)
-                    as_ = rffi.cast(ASN1_STRING, as_)
-                    buf = libssl_ASN1_STRING_data(as_)
-                    length = libssl_ASN1_STRING_length(as_)
-                    w_t = space.newtuple([
-                        v, space.wrap(rffi.charpsize2str(buf, length))])
-                else:
-                    # for everything else, we use the OpenSSL print form
-                    if gntype not in (GEN_OTHERNAME, GEN_X400, GEN_EDIPARTY,
-                                      GEN_IPADD, GEN_RID):
-                        space.warn(space.wrap("Unknown general name type"),
-                                   space.w_RuntimeWarning)
-                    libssl_BIO_reset(biobuf)
-                    libssl_GENERAL_NAME_print(biobuf, name)
-                    with lltype.scoped_alloc(rffi.CCHARP.TO, 2048) as buf:
-                        length = libssl_BIO_gets(biobuf, buf, 2047)
-                        if length < 0:
-                            raise _ssl_seterror(space, None, 0)
+                        # for everything else, we use the OpenSSL print form
+                        if gntype not in (GEN_OTHERNAME, GEN_X400, GEN_EDIPARTY,
+                                          GEN_IPADD, GEN_RID):
+                            space.warn(space.wrap("Unknown general name type"),
+                                       space.w_RuntimeWarning)
+                        libssl_BIO_reset(biobuf)
+                        libssl_GENERAL_NAME_print(biobuf, name)
+                        with lltype.scoped_alloc(rffi.CCHARP.TO, 2048) as buf:
+                            length = libssl_BIO_gets(biobuf, buf, 2047)
+                            if length < 0:
+                                raise _ssl_seterror(space, None, 0)
 
-                        v = rffi.charpsize2str(buf, length)
-                    v1, v2 = v.split(':', 1)
-                    w_t = space.newtuple([space.wrap(v1),
-                                          space.wrap(v2)])
+                            v = rffi.charpsize2str(buf, length)
+                        v1, v2 = v.split(':', 1)
+                        w_t = space.newtuple([space.wrap(v1),
+                                              space.wrap(v2)])
 
-                alt_names_w.append(w_t)
+                    alt_names_w.append(w_t)
+            finally:
+                libssl_pypy_GENERAL_NAME_pop_free(names)
     finally:
         libssl_BIO_free(biobuf)
 
@@ -921,8 +924,11 @@
         length = libssl_ASN1_STRING_to_UTF8(buf_ptr, value)
         if length < 0:
             raise _ssl_seterror(space, None, 0)
-        w_value = space.wrap(rffi.charpsize2str(buf_ptr[0], length))
-        w_value = space.call_method(w_value, "decode", space.wrap("utf-8"))
+        try:
+            w_value = space.wrap(rffi.charpsize2str(buf_ptr[0], length))
+            w_value = space.call_method(w_value, "decode", space.wrap("utf-8"))
+        finally:
+            libssl_OPENSSL_free(buf_ptr[0])
 
     return space.newtuple([w_name, w_value])
 
@@ -930,9 +936,10 @@
 def _get_aia_uri(space, certificate, nid):
     info = rffi.cast(AUTHORITY_INFO_ACCESS, libssl_X509_get_ext_d2i(
         certificate, NID_info_access, None, None))
-    if not info or libssl_sk_ACCESS_DESCRIPTION_num(info) == 0:
-        return
     try:
+        if not info or libssl_sk_ACCESS_DESCRIPTION_num(info) == 0:
+            return
+
         result_w = []
         for i in range(libssl_sk_ACCESS_DESCRIPTION_num(info)):
             ad = libssl_sk_ACCESS_DESCRIPTION_value(info, i)
@@ -962,20 +969,24 @@
     if not dps:
         return None
 
-    cdp_w = []
-    for i in range(libssl_sk_DIST_POINT_num(dps)):
-        dp = libssl_sk_DIST_POINT_value(dps, i)
-        gns = libssl_pypy_DIST_POINT_fullname(dp)
+    try:
+        cdp_w = []
+        for i in range(libssl_sk_DIST_POINT_num(dps)):
+            dp = libssl_sk_DIST_POINT_value(dps, i)
+            gns = libssl_pypy_DIST_POINT_fullname(dp)
 
-        for j in range(libssl_sk_GENERAL_NAME_num(gns)):
-            name = libssl_sk_GENERAL_NAME_value(gns, j)
-            gntype = intmask(name.c_type)
-            if gntype != GEN_URI:
-                continue
-            uri = libssl_pypy_GENERAL_NAME_uri(name)
-            length = intmask(uri.c_length)
-            s_uri = rffi.charpsize2str(uri.c_data, length)
-            cdp_w.append(space.wrap(s_uri))
+            for j in range(libssl_sk_GENERAL_NAME_num(gns)):
+                name = libssl_sk_GENERAL_NAME_value(gns, j)
+                gntype = intmask(name.c_type)
+                if gntype != GEN_URI:
+                    continue
+                uri = libssl_pypy_GENERAL_NAME_uri(name)
+                length = intmask(uri.c_length)
+                s_uri = rffi.charpsize2str(uri.c_data, length)
+                cdp_w.append(space.wrap(s_uri))
+    finally:
+        if OPENSSL_VERSION_NUMBER < 0x10001000:
+            libssl_sk_DIST_POINT_free(dps)
     return space.newtuple(cdp_w[:])
 
 def checkwait(space, w_sock, writing):
@@ -1270,6 +1281,7 @@
         if not ctx:
             raise ssl_error(space, "failed to allocate SSL context")
 
+        rgc.add_memory_pressure(10 * 1024 * 1024)
         self = space.allocate_instance(_SSLContext, w_subtype)
         self.ctx = ctx
         self.check_hostname = False
@@ -1296,6 +1308,9 @@
 
         return self
 
+    def __del__(self):
+        libssl_SSL_CTX_free(self.ctx)
+
     @unwrap_spec(server_side=int)
     def descr_wrap_socket(self, space, w_sock, server_side, w_server_hostname=None, w_ssl_sock=None):
         return _SSLSocket.descr_new(space, self, w_sock, server_side, w_server_hostname, w_ssl_sock)
diff --git a/pypy/module/micronumpy/test/test_object_arrays.py b/pypy/module/micronumpy/test/test_object_arrays.py
--- a/pypy/module/micronumpy/test/test_object_arrays.py
+++ b/pypy/module/micronumpy/test/test_object_arrays.py
@@ -178,6 +178,7 @@
         assert 'a' * 100 in str(a)
         b = a.astype('U')
         assert b.dtype == 'U100'
+        assert 'a' * 100 in str(b)
 
         a = np.array([123], dtype='U')
         assert a[0] == u'123'
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -2259,7 +2259,10 @@
     def coerce(self, space, dtype, w_item):
         if isinstance(w_item, boxes.W_UnicodeBox):
             return w_item
-        value = space.unicode_w(space.unicode_from_object(w_item))
+        if isinstance(w_item, boxes.W_ObjectBox):
+            value = space.unicode_w(space.unicode_from_object(w_item.w_obj))
+        else:
+            value = space.unicode_w(space.unicode_from_object(w_item))
         return boxes.W_UnicodeBox(value)
 
     def store(self, arr, i, offset, box, native):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -248,3 +248,23 @@
         loop, = log.loops_by_filename(self.filepath)
         ops = loop.ops_by_id('getitem', include_guard_not_invalidated=False)
         assert log.opnames(ops) == []
+
+    def test_enumerate_list(self):
+        def main(n):
+            for a, b in enumerate([1, 2] * 1000):
+                a + b
+
+        log = self.run(main, [1000])
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
+
+    def test_enumerate(self):
+        def main(n):
+            for a, b in enumerate("abc" * 1000):
+                a + ord(b)
+
+        log = self.run(main, [1000])
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -757,10 +757,11 @@
         p = ffi.cast("long long", ffi.cast("wchar_t", -1))
         if SIZE_OF_WCHAR == 2:      # 2 bytes, unsigned
             assert int(p) == 0xffff
-        elif platform.machine().startswith(('arm', 'aarch64')):
-            assert int(p) == 0xffffffff      # 4 bytes, unsigned
-        else:                       # 4 bytes, signed
+        elif (sys.platform.startswith('linux') and
+              platform.machine().startswith('x86')):   # known to be signed
             assert int(p) == -1
+        else:                     # in general, it can be either signed or not
+            assert int(p) in [-1, 0xffffffff]  # e.g. on arm, both cases occur
         p = ffi.cast("int", u+'\u1234')
         assert int(p) == 0x1234
 
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py
@@ -262,7 +262,8 @@
     ffi = FFI()
     ffi.cdef("typedef int bool, *FILE;")
     assert repr(ffi.cast("bool", 123)) == "<cdata 'int' 123>"
-    assert repr(ffi.cast("FILE", 123)) == "<cdata 'int *' 0x7b>"
+    assert re.match(r"<cdata 'int [*]' 0[xX]?0*7[bB]>",
+                    repr(ffi.cast("FILE", 123)))
     ffi = FFI()
     ffi.cdef("typedef bool (*fn_t)(bool, bool);")   # "bool," but within "( )"
 
@@ -273,6 +274,13 @@
     ffi = FFI()
     ffi.cdef("typedef _Bool bool; void f(bool);")
 
+def test_unknown_argument_type():
+    ffi = FFI()
+    e = py.test.raises(CDefError, ffi.cdef, "void f(foobarbazzz);")
+    assert str(e.value) == ("f arg 1: unknown type 'foobarbazzz' (if you meant"
+                            " to use the old C syntax of giving untyped"
+                            " arguments, it is not supported)")
+
 def test_void_renamed_as_only_arg():
     ffi = FFI()
     ffi.cdef("typedef void void_t1;"
@@ -280,38 +288,16 @@
              "typedef int (*func_t)(void_t);")
     assert ffi.typeof("func_t").args == ()
 
-def test_win_common_types():
-    from cffi.commontypes import COMMON_TYPES, _CACHE
-    from cffi.commontypes import win_common_types, resolve_common_type
-    #
-    def clear_all(extra={}, old_dict=COMMON_TYPES.copy()):
-        COMMON_TYPES.clear()
-        COMMON_TYPES.update(old_dict)
-        COMMON_TYPES.update(extra)
-        _CACHE.clear()
-    #
-    for maxsize in [2**32-1, 2**64-1]:
-        ct = win_common_types(maxsize)
-        clear_all(ct)
-        for key in sorted(ct):
-            if ct[key] != 'set-unicode-needed':
-                resolve_common_type(key)
-    # assert did not crash
-    # now try to use e.g. WPARAM (-> UINT_PTR -> unsigned 32/64-bit)
-    for maxsize in [2**32-1, 2**64-1]:
-        ct = win_common_types(maxsize)
-        clear_all(ct)
-        ffi = FFI()
-        value = int(ffi.cast("WPARAM", -1))
-        assert value == maxsize
-    #
-    clear_all()
-
 def test_WPARAM_on_windows():
     if sys.platform != 'win32':
         py.test.skip("Only for Windows")
     ffi = FFI()
     ffi.cdef("void f(WPARAM);")
+    #
+    # WPARAM -> UINT_PTR -> unsigned 32/64-bit integer
+    ffi = FFI()
+    value = int(ffi.cast("WPARAM", -42))
+    assert value == sys.maxsize * 2 - 40
 
 def test__is_constant_globalvar():
     for input, expected_output in [
@@ -361,6 +347,41 @@
     assert lst[0] == lst[2]
     assert lst[1] == lst[3]
 
+def test_const_pointer_to_pointer():
+    from cffi import model
+    ffi = FFI(backend=FakeBackend())
+    #
+    tp, qual = ffi._parser.parse_type_and_quals("char * * (* const)")
+    assert (str(tp), qual) == ("<char * * *>", model.Q_CONST)
+    tp, qual = ffi._parser.parse_type_and_quals("char * (* const (*))")
+    assert (str(tp), qual) == ("<char * * const *>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals("char (* const (* (*)))")
+    assert (str(tp), qual) == ("<char * const * *>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals("char const * * *")
+    assert (str(tp), qual) == ("<char const * * *>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals("const char * * *")
+    assert (str(tp), qual) == ("<char const * * *>", 0)
+    #
+    tp, qual = ffi._parser.parse_type_and_quals("char * * * const const")
+    assert (str(tp), qual) == ("<char * * *>", model.Q_CONST)
+    tp, qual = ffi._parser.parse_type_and_quals("char * * volatile *")
+    assert (str(tp), qual) == ("<char * * volatile *>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals("char * volatile restrict * *")
+    assert (str(tp), qual) == ("<char * __restrict volatile * *>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals("char const volatile * * *")
+    assert (str(tp), qual) == ("<char volatile const * * *>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals("const char * * *")
+    assert (str(tp), qual) == ("<char const * * *>", 0)
+    #
+    tp, qual = ffi._parser.parse_type_and_quals(
+        "int(char*const*, short****const*)")
+    assert (str(tp), qual) == (
+        "<int()(char * const *, short * * * * const *)>", 0)
+    tp, qual = ffi._parser.parse_type_and_quals(
+        "char*const*(short*const****)")
+    assert (str(tp), qual) == (
+        "<char * const *()(short * const * * * *)>", 0)
+
 def test_enum():
     ffi = FFI()
     ffi.cdef("""
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py
@@ -396,3 +396,23 @@
         return ffi.NULL
     alloc5 = ffi.new_allocator(myalloc5)
     py.test.raises(MemoryError, alloc5, "int[5]")
+
+def test_bool_issue228():
+    ffi = _cffi1_backend.FFI()
+    fntype = ffi.typeof("int(*callback)(bool is_valid)")
+    assert repr(fntype.args[0]) == "<ctype '_Bool'>"
+
+def test_FILE_issue228():
+    fntype1 = _cffi1_backend.FFI().typeof("FILE *")
+    fntype2 = _cffi1_backend.FFI().typeof("FILE *")
+    assert repr(fntype1) == "<ctype 'FILE *'>"
+    assert fntype1 is fntype2
+
+def test_cast_from_int_type_to_bool():
+    ffi = _cffi1_backend.FFI()
+    for basetype in ['char', 'short', 'int', 'long', 'long long']:
+        for sign in ['signed', 'unsigned']:
+            type = '%s %s' % (sign, basetype)
+            assert int(ffi.cast("_Bool", ffi.cast(type, 42))) == 1


More information about the pypy-commit mailing list