[pypy-commit] pypy cling-support: merge default into cling-support branch and fix dummy_backend

wlav pypy.commits at gmail.com
Tue Dec 13 18:53:14 EST 2016


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: cling-support
Changeset: r89048:2cf0e94f1f19
Date: 2016-12-12 17:30 -0800
http://bitbucket.org/pypy/pypy/changeset/2cf0e94f1f19/

Log:	merge default into cling-support branch and fix dummy_backend

diff too long, truncating to 2000 out of 7197 lines

diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py
--- a/lib-python/2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/2.7/distutils/sysconfig_pypy.py
@@ -12,7 +12,6 @@
 
 import sys
 import os
-import shlex
 import imp
 
 from distutils.errors import DistutilsPlatformError
@@ -62,11 +61,31 @@
 def _init_posix():
     """Initialize the module as appropriate for POSIX systems."""
     g = {}
+    g['CC'] = "gcc -pthread"
+    g['CXX'] = "g++ -pthread"
+    g['OPT'] = "-DNDEBUG -O2"
+    g['CFLAGS'] = "-DNDEBUG -O2"
+    g['CCSHARED'] = "-fPIC"
+    g['LDSHARED'] = "gcc -pthread -shared"
+    g['SO'] = [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION][0]
+    g['AR'] = "ar"
+    g['ARFLAGS'] = "rc"
     g['EXE'] = ""
-    g['SO'] = [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION][0]
     g['LIBDIR'] = os.path.join(sys.prefix, 'lib')
-    g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check
-    g['OPT'] = "" 
+    g['VERSION'] = get_python_version()
+
+    if sys.platform[:6] == "darwin":
+        import platform
+        if platform.machine() == 'i386':
+            if platform.architecture()[0] == '32bit':
+                arch = 'i386'
+            else:
+                arch = 'x86_64'
+        else:
+            # just a guess
+            arch = platform.machine()
+        g['LDSHARED'] += ' -undefined dynamic_lookup'
+        g['CC'] += ' -arch %s' % (arch,)
 
     global _config_vars
     _config_vars = g
@@ -103,6 +122,12 @@
         _config_vars['prefix'] = PREFIX
         _config_vars['exec_prefix'] = EXEC_PREFIX
 
+        # OS X platforms require special customization to handle
+        # multi-architecture, multi-os-version installers
+        if sys.platform == 'darwin':
+            import _osx_support
+            _osx_support.customize_config_vars(_config_vars)
+
     if args:
         vals = []
         for name in args:
@@ -118,30 +143,80 @@
     """
     return get_config_vars().get(name)
 
+
 def customize_compiler(compiler):
-    """Dummy method to let some easy_install packages that have
-    optional C speedup components.
+    """Do any platform-specific customization of a CCompiler instance.
+
+    Mainly needed on Unix, so we can plug in the information that
+    varies across Unices and is stored in Python's Makefile (CPython)
+    or hard-coded in _init_posix() (PyPy).
     """
-    def customize(executable, flags):
-        command = compiler.executables[executable] + flags
-        setattr(compiler, executable, command)
+    if compiler.compiler_type == "unix":
+        if sys.platform == "darwin":
+            # Perform first-time customization of compiler-related
+            # config vars on OS X now that we know we need a compiler.
+            # This is primarily to support Pythons from binary
+            # installers.  The kind and paths to build tools on
+            # the user system may vary significantly from the system
+            # that Python itself was built on.  Also the user OS
+            # version and build tools may not support the same set
+            # of CPU architectures for universal builds.
+            global _config_vars
+            # Use get_config_var() to ensure _config_vars is initialized.
+            if not get_config_var('CUSTOMIZED_OSX_COMPILER'):
+                import _osx_support
+                _osx_support.customize_compiler(_config_vars)
+                _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
 
-    if compiler.compiler_type == "unix":
-        # compiler_so can be c++ which has no -Wimplicit
-        #compiler.compiler_so.extend(['-O2', '-fPIC', '-Wimplicit'])
-        compiler.compiler_so.extend(['-O2', '-fPIC'])
-        compiler.shared_lib_extension = get_config_var('SO')
-        if "CPPFLAGS" in os.environ:
-            cppflags = shlex.split(os.environ["CPPFLAGS"])
-            for executable in ('compiler', 'compiler_so', 'linker_so'):
-                customize(executable, cppflags)
-        if "CFLAGS" in os.environ:
-            cflags = shlex.split(os.environ["CFLAGS"])
-            for executable in ('compiler', 'compiler_so', 'linker_so'):
-                customize(executable, cflags)
-        if "LDFLAGS" in os.environ:
-            ldflags = shlex.split(os.environ["LDFLAGS"])
-            customize('linker_so', ldflags)
+        (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
+            get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
+                            'CCSHARED', 'LDSHARED', 'SO', 'AR',
+                            'ARFLAGS')
+
+        if 'CC' in os.environ:
+            newcc = os.environ['CC']
+            if (sys.platform == 'darwin'
+                    and 'LDSHARED' not in os.environ
+                    and ldshared.startswith(cc)):
+                # On OS X, if CC is overridden, use that as the default
+                #       command for LDSHARED as well
+                ldshared = newcc + ldshared[len(cc):]
+            cc = newcc
+        if 'CXX' in os.environ:
+            cxx = os.environ['CXX']
+        if 'LDSHARED' in os.environ:
+            ldshared = os.environ['LDSHARED']
+        if 'CPP' in os.environ:
+            cpp = os.environ['CPP']
+        else:
+            cpp = cc + " -E"           # not always
+        if 'LDFLAGS' in os.environ:
+            ldshared = ldshared + ' ' + os.environ['LDFLAGS']
+        if 'CFLAGS' in os.environ:
+            cflags = opt + ' ' + os.environ['CFLAGS']
+            ldshared = ldshared + ' ' + os.environ['CFLAGS']
+        if 'CPPFLAGS' in os.environ:
+            cpp = cpp + ' ' + os.environ['CPPFLAGS']
+            cflags = cflags + ' ' + os.environ['CPPFLAGS']
+            ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
+        if 'AR' in os.environ:
+            ar = os.environ['AR']
+        if 'ARFLAGS' in os.environ:
+            archiver = ar + ' ' + os.environ['ARFLAGS']
+        else:
+            archiver = ar + ' ' + ar_flags
+
+        cc_cmd = cc + ' ' + cflags
+        compiler.set_executables(
+            preprocessor=cpp,
+            compiler=cc_cmd,
+            compiler_so=cc_cmd + ' ' + ccshared,
+            compiler_cxx=cxx,
+            linker_so=ldshared,
+            linker_exe=cc,
+            archiver=archiver)
+
+        compiler.shared_lib_extension = so_ext
 
 
 from sysconfig_cpython import (
diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py
--- a/lib_pypy/_pypy_wait.py
+++ b/lib_pypy/_pypy_wait.py
@@ -1,3 +1,4 @@
+import os
 from resource import ffi, lib, _make_struct_rusage
 
 __all__ = ["wait3", "wait4"]
@@ -7,6 +8,9 @@
     status = ffi.new("int *")
     ru = ffi.new("struct rusage *")
     pid = lib.wait3(status, options, ru)
+    if pid == -1:
+        errno = ffi.errno
+        raise OSError(errno, os.strerror(errno))
 
     rusage = _make_struct_rusage(ru)
 
@@ -16,6 +20,9 @@
     status = ffi.new("int *")
     ru = ffi.new("struct rusage *")
     pid = lib.wait4(pid, status, options, ru)
+    if pid == -1:
+        errno = ffi.errno
+        raise OSError(errno, os.strerror(errno))
 
     rusage = _make_struct_rusage(ru)
 
diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info
--- a/lib_pypy/greenlet.egg-info
+++ b/lib_pypy/greenlet.egg-info
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: greenlet
-Version: 0.4.10
+Version: 0.4.11
 Summary: Lightweight in-process concurrent programming
 Home-page: https://github.com/python-greenlet/greenlet
 Author: Ralf Schmitt (for CPython), PyPy team
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,7 +1,7 @@
 import sys
 import _continuation
 
-__version__ = "0.4.10"
+__version__ = "0.4.11"
 
 # ____________________________________________________________
 # Exceptions
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -1,31 +1,19 @@
 cppyy: C++ bindings for PyPy
 ============================
 
-The cppyy module creates, at run-time, Python-side classes and functions for
-C++, by querying a C++ reflection system.
-The default system used is `Reflex`_, which extracts the needed information
-from C++ header files.
-Another current backend is based on `CINT`_, and yet another, more important
-one for the medium- to long-term will be based on `cling`_.
-The latter sits on top of `llvm`_'s `clang`_, and will therefore allow the use
-of C++11.
-The work on the cling backend has so far been done only for CPython, but
-bringing it to PyPy is a lot less work than developing it in the first place.
+The cppyy module delivers dynamic Python-C++ bindings.
+It is based on `Cling`_ which, through `LLVM`_/`clang`_, provides C++
+reflection as extracted from header files.
+The module itself is built into PyPy (an alternative exists for CPython), but
+it requires a backend, installable through pip, to interface with Cling.
 
-.. _Reflex: https://root.cern.ch/how/how-use-reflex
-.. _CINT: https://root.cern.ch/introduction-cint
-.. _cling: https://root.cern.ch/cling
-.. _llvm: http://llvm.org/
+.. _Cling: https://root.cern.ch/cling
+.. _LLVM: http://llvm.org/
 .. _clang: http://clang.llvm.org/
 
-This document describes the version of cppyy that lives in the main branch of
-PyPy.
-The development of cppyy happens in the "reflex-support" branch.
-
 
 Motivation
 ----------
-
 To provide bindings to another language in CPython, you program to a
 generic C-API that exposes many of the interpreter features.
 With PyPy, however, there is no such generic C-API, because several of the
@@ -47,7 +35,7 @@
 by the JIT up until the actual point of call into C++.
 This means for example, that if variables are already unboxed by the JIT, they
 can be passed through directly to C++.
-Second, a backend such as Reflex (and cling far more so) adds dynamic features
+Second, a backend such as Cling adds dynamic features
 to C++, thus greatly reducing impedance mismatches between the two languages.
 For example, Reflex is dynamic enough to allow writing runtime bindings
 generation in python (as opposed to RPython) and this is used to create very
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -71,8 +71,11 @@
 Analyzing performance of applications is always tricky. We have various
 tools, for example a `jitviewer`_ that help us analyze performance.
 
-The jitviewer shows the code generated by the PyPy JIT in a hierarchical way,
-as shown by the screenshot below:
+The old tool was partly rewritten and combined with vmprof. The service is
+hosted at `vmprof.com`_.
+
+The following shows an old image of the jitviewer.
+The code generated by the PyPy JIT in a hierarchical way:
 
   - at the bottom level, it shows the Python source code of the compiled loops
 
@@ -84,13 +87,17 @@
 
 .. image:: image/jitviewer.png
 
-The jitviewer is a web application based on flask and jinja2 (and jQuery on
-the client): if you have great web developing skills and want to help PyPy,
+The jitviewer is a web application based on django and angularjs:
+if you have great web developing skills and want to help PyPy,
 this is an ideal task to get started, because it does not require any deep
-knowledge of the internals.
+knowledge of the internals. Head over to `vmprof-python`_, `vmprof-server`_ and
+`vmprof-integration`_ to find open issues and documentation.
 
-.. _jitviewer: http://bitbucket.org/pypy/jitviewer
-
+.. _jitviewer: http://vmprof.com
+.. _vmprof.com: http://vmprof.com
+.. _vmprof-python: https://github.com/vmprof/vmprof-python
+.. _vmprof-server: https://github.com/vmprof/vmprof-server
+.. _vmprof-integration: https://github.com/vmprof/vmprof-integration
 
 Optimized Unicode Representation
 --------------------------------
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
@@ -5,6 +5,15 @@
 .. this is a revision shortly after release-pypy2.7-v5.6
 .. startrev: 7e9787939641
 
+
+Since a while now, PyPy preserves the order of dictionaries and sets.
+However, the set literal syntax ``{x, y, z}`` would by mistake build a
+set with the opposite order: ``set([z, y, x])``.  This has been fixed.
+Note that CPython is inconsistent too: in 2.7.12, ``{5, 5.0}`` would be
+``set([5.0])``, but in 2.7.trunk it is ``set([5])``.  PyPy's behavior
+changed in exactly the same way because of this fix.
+
+
 .. branch: rpython-error-to-systemerror
 
 Any uncaught RPython exception (from a PyPy bug) is turned into an
@@ -20,3 +29,19 @@
 .. branch: clean-exported-state
 
 Clean-ups in the jit optimizeopt
+
+.. branch: conditional_call_value_4
+
+Add jit.conditional_call_elidable(), a way to tell the JIT "conditonally
+call this function" returning a result.
+
+.. branch: desc-specialize
+
+Refactor FunctionDesc.specialize() and related code (RPython annotator).
+
+.. branch: raw-calloc
+
+.. branch: issue2446
+
+Assign ``tp_doc`` to the new TypeObject's type dictionary ``__doc__`` key
+so it will be picked up by app-level objects of that type
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -298,6 +298,12 @@
         if config.translation.sandbox:
             config.objspace.lonepycfiles = False
 
+        if config.objspace.usemodules.cpyext:
+            if config.translation.gc != 'incminimark':
+                raise Exception("The 'cpyext' module requires the 'incminimark'"
+                                " GC.  You need either 'targetpypystandalone.py"
+                                " --withoutmod-cpyext' or '--gc=incminimark'")
+
         config.translating = True
 
         import translate
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -111,7 +111,9 @@
                 self.keywords = self.keywords + keywords
                 self.keywords_w = self.keywords_w + values_w
             return
+        is_dict = False
         if space.isinstance_w(w_starstararg, space.w_dict):
+            is_dict = True
             keys_w = space.unpackiterable(w_starstararg)
         else:
             try:
@@ -125,7 +127,9 @@
             keys_w = space.unpackiterable(w_keys)
         keywords_w = [None] * len(keys_w)
         keywords = [None] * len(keys_w)
-        _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords, keywords_w, self.keywords)
+        _do_combine_starstarargs_wrapped(
+            space, keys_w, w_starstararg, keywords, keywords_w, self.keywords,
+            is_dict)
         self.keyword_names_w = keys_w
         if self.keywords is None:
             self.keywords = keywords
@@ -355,7 +359,7 @@
                             key)
 
 def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords,
-        keywords_w, existingkeywords):
+        keywords_w, existingkeywords, is_dict):
     i = 0
     for w_key in keys_w:
         try:
@@ -374,7 +378,16 @@
                             "got multiple values for keyword argument '%s'",
                             key)
         keywords[i] = key
-        keywords_w[i] = space.getitem(w_starstararg, w_key)
+        if is_dict:
+            # issue 2435: bug-to-bug compatibility with cpython. for a subclass of
+            # dict, just ignore the __getitem__ and access the underlying dict
+            # directly
+            from pypy.objspace.descroperation import dict_getitem
+            w_descr = dict_getitem(space)
+            w_value = space.get_and_call_function(w_descr, w_starstararg, w_key)
+        else:
+            w_value = space.getitem(w_starstararg, w_key)
+        keywords_w[i] = w_value
         i += 1
 
 @jit.look_inside_iff(
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -183,6 +183,14 @@
                 assert self._finalize_.im_func is not W_Root._finalize_.im_func
             space.finalizer_queue.register_finalizer(self)
 
+    def may_unregister_rpython_finalizer(self, space):
+        """Optimization hint only: if there is no user-defined __del__()
+        method, pass the hint ``don't call any finalizer'' to rgc.
+        """
+        if not self.getclass(space).hasuserdel:
+            from rpython.rlib import rgc
+            rgc.may_ignore_finalizer(self)
+
     # hooks that the mapdict implementations needs:
     def _get_mapdict_map(self):
         return None
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -439,6 +439,7 @@
                                           space.wrap(msg))
         return OperationError(exc, w_error)
 
+ at specialize.arg(3)
 def wrap_oserror2(space, e, w_filename=None, exception_name='w_OSError',
                   w_exception_class=None):
     assert isinstance(e, OSError)
@@ -466,8 +467,8 @@
         w_error = space.call_function(exc, space.wrap(errno),
                                       space.wrap(msg))
     return OperationError(exc, w_error)
-wrap_oserror2._annspecialcase_ = 'specialize:arg(3)'
 
+ at specialize.arg(3)
 def wrap_oserror(space, e, filename=None, exception_name='w_OSError',
                  w_exception_class=None):
     if filename is not None:
@@ -478,7 +479,6 @@
         return wrap_oserror2(space, e, None,
                              exception_name=exception_name,
                              w_exception_class=w_exception_class)
-wrap_oserror._annspecialcase_ = 'specialize:arg(3)'
 
 def exception_from_saved_errno(space, w_type):
     from rpython.rlib.rposix import get_saved_errno
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -547,6 +547,8 @@
 
     @jit.dont_look_inside
     def _run_finalizers(self):
+        # called by perform() when we have to "perform" this action,
+        # and also directly at the end of gc.collect).
         while True:
             w_obj = self.space.finalizer_queue.next_dead()
             if w_obj is None:
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -2,7 +2,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.pyopcode import LoopBlock
 from pypy.interpreter.pycode import CO_YIELD_INSIDE_TRY
-from rpython.rlib import jit
+from rpython.rlib import jit, rgc
 
 
 class GeneratorIterator(W_Root):
@@ -103,11 +103,11 @@
                 w_result = frame.execute_frame(w_arg, operr)
             except OperationError:
                 # errors finish a frame
-                self.frame = None
+                self.frame_is_finished()
                 raise
             # if the frame is now marked as finished, it was RETURNed from
             if frame.frame_finished_execution:
-                self.frame = None
+                self.frame_is_finished()
                 raise OperationError(space.w_StopIteration, space.w_None)
             else:
                 return w_result     # YIELDed
@@ -209,7 +209,7 @@
             finally:
                 frame.f_backref = jit.vref_None
                 self.running = False
-                self.frame = None
+                self.frame_is_finished()
         return unpack_into
     unpack_into = _create_unpack_into()
     unpack_into_w = _create_unpack_into()
@@ -228,6 +228,10 @@
                     break
                 block = block.previous
 
+    def frame_is_finished(self):
+        self.frame = None
+        rgc.may_ignore_finalizer(self)
+
 
 def get_printable_location_genentry(bytecode):
     return '%s <generator>' % (bytecode.get_repr(),)
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1295,9 +1295,10 @@
     @jit.unroll_safe
     def BUILD_SET(self, itemcount, next_instr):
         w_set = self.space.newset()
-        for i in range(itemcount):
-            w_item = self.popvalue()
+        for i in range(itemcount-1, -1, -1):
+            w_item = self.peekvalue(i)
             self.space.call_method(w_set, 'add', w_item)
+        self.popvalues(itemcount)
         self.pushvalue(w_set)
 
     def STORE_MAP(self, oparg, next_instr):
diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -120,6 +120,12 @@
             raise OperationError(AttributeError, name)
         return method(*args)
 
+    def lookup_in_type(self, cls, name):
+        return getattr(cls, name)
+
+    def get_and_call_function(self, w_descr, w_obj, *args):
+        return w_descr.__get__(w_obj)(*args)
+
     def type(self, obj):
         class Type:
             def getname(self, space):
@@ -805,3 +811,19 @@
             assert str(e) == "myerror"
         else:
             assert False, "Expected TypeError"
+
+    def test_dict_subclass_with_weird_getitem(self):
+        # issue 2435: bug-to-bug compatibility with cpython. for a subclass of
+        # dict, just ignore the __getitem__ and behave like ext_do_call in ceval.c
+        # which just uses the underlying dict
+        class d(dict):
+            def __getitem__(self, key):
+                return key
+
+        for key in ["foo", u"foo"]:
+            q = d()
+            q[key] = "bar"
+
+            def test(**kwargs):
+                return kwargs
+            assert test(**q) == {"foo": "bar"}
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -729,6 +729,10 @@
 
 
 class AppTestCompiler:
+    def setup_class(cls):
+        cls.w_host_is_pypy = cls.space.wrap(
+            '__pypy__' in sys.builtin_module_names)
+
     def test_bom_with_future(self):
         s = '\xef\xbb\xbffrom __future__ import division\nx = 1/2'
         ns = {}
@@ -771,6 +775,18 @@
         assert math.copysign(1., c[0]) == -1.0
         assert math.copysign(1., c[1]) == -1.0
 
+    def test_dict_and_set_literal_order(self):
+        x = 1
+        l1 = list({1:'a', 3:'b', 2:'c', 4:'d'})
+        l2 = list({1, 3, 2, 4})
+        l3 = list({x:'a', 3:'b', 2:'c', 4:'d'})
+        l4 = list({x, 3, 2, 4})
+        if not self.host_is_pypy:
+            # the full test relies on the host Python providing ordered dicts
+            assert set(l1) == set(l2) == set(l3) == set(l4) == {1, 3, 2, 4}
+        else:
+            assert l1 == l2 == l3 == l4 == [1, 3, 2, 4]
+
 
 ##class TestPythonAstCompiler(BaseTestCompiler):
 ##    def setup_method(self, method):
diff --git a/pypy/interpreter/test/test_pyframe.py b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -580,3 +580,25 @@
             pass
         sys.settrace(None)
         assert seen == ['call', 'exception', 'return']
+
+    def test_generator_trace_stopiteration(self):
+        import sys
+        def f():
+            yield 5
+        gen = f()
+        assert next(gen) == 5
+        seen = []
+        def trace_func(frame, event, *args):
+            print('TRACE:', frame, event, args)
+            seen.append(event)
+            return trace_func
+        def g():
+            for x in gen:
+                never_entered
+        sys.settrace(trace_func)
+        g()
+        sys.settrace(None)
+        print 'seen:', seen
+        # on Python 3 we get an extra 'exception' when 'for' catches
+        # StopIteration
+        assert seen == ['call', 'line', 'call', 'return', 'return']
diff --git a/pypy/interpreter/test/test_special.py b/pypy/interpreter/test/test_special.py
--- a/pypy/interpreter/test/test_special.py
+++ b/pypy/interpreter/test/test_special.py
@@ -4,9 +4,11 @@
     def test_Ellipsis(self):
         assert Ellipsis == Ellipsis
         assert repr(Ellipsis) == 'Ellipsis'
+        assert Ellipsis.__class__.__name__ == 'ellipsis'
     
     def test_NotImplemented(self):
         def f():
             return NotImplemented
         assert f() == NotImplemented 
         assert repr(NotImplemented) == 'NotImplemented'
+        assert NotImplemented.__class__.__name__ == 'NotImplementedType'
diff --git a/pypy/interpreter/test/test_unicodehelper.py b/pypy/interpreter/test/test_unicodehelper.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/test/test_unicodehelper.py
@@ -0,0 +1,26 @@
+from pypy.interpreter.unicodehelper import encode_utf8, decode_utf8
+
+class FakeSpace:
+    pass
+
+def test_encode_utf8():
+    space = FakeSpace()
+    assert encode_utf8(space, u"abc") == "abc"
+    assert encode_utf8(space, u"\u1234") == "\xe1\x88\xb4"
+    assert encode_utf8(space, u"\ud800") == "\xed\xa0\x80"
+    assert encode_utf8(space, u"\udc00") == "\xed\xb0\x80"
+    # for the following test, go to lengths to avoid CPython's optimizer
+    # and .pyc file storage, which collapse the two surrogates into one
+    c = u"\udc00"
+    assert encode_utf8(space, u"\ud800" + c) == "\xf0\x90\x80\x80"
+
+def test_decode_utf8():
+    space = FakeSpace()
+    assert decode_utf8(space, "abc") == u"abc"
+    assert decode_utf8(space, "\xe1\x88\xb4") == u"\u1234"
+    assert decode_utf8(space, "\xed\xa0\x80") == u"\ud800"
+    assert decode_utf8(space, "\xed\xb0\x80") == u"\udc00"
+    got = decode_utf8(space, "\xed\xa0\x80\xed\xb0\x80")
+    assert map(ord, got) == [0xd800, 0xdc00]
+    got = decode_utf8(space, "\xf0\x90\x80\x80")
+    assert map(ord, got) == [0x10000]
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -770,12 +770,12 @@
 )
 assert not Cell.typedef.acceptable_as_base_class  # no __new__
 
-Ellipsis.typedef = TypeDef("Ellipsis",
+Ellipsis.typedef = TypeDef("ellipsis",
     __repr__ = interp2app(Ellipsis.descr__repr__),
 )
 assert not Ellipsis.typedef.acceptable_as_base_class  # no __new__
 
-NotImplemented.typedef = TypeDef("NotImplemented",
+NotImplemented.typedef = TypeDef("NotImplementedType",
     __repr__ = interp2app(NotImplemented.descr__repr__),
 )
 assert not NotImplemented.typedef.acceptable_as_base_class  # no __new__
diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py
--- a/pypy/interpreter/unicodehelper.py
+++ b/pypy/interpreter/unicodehelper.py
@@ -51,6 +51,10 @@
     return result
 
 def decode_utf8(space, string):
+    # Surrogates are accepted and not treated specially at all.
+    # If there happen to be two 3-bytes encoding a pair of surrogates,
+    # you still get two surrogate unicode characters in the result.
+    # These are the Python2 rules; Python3 differs.
     result, consumed = runicode.str_decode_utf_8(
         string, len(string), "strict",
         final=True, errorhandler=decode_error_handler(space),
@@ -59,8 +63,9 @@
 
 def encode_utf8(space, uni):
     # Note that this function never raises UnicodeEncodeError,
-    # since surrogate pairs are allowed.
-    # This is not the case with Python3.
+    # since surrogates are allowed, either paired or lone.
+    # A paired surrogate is considered like the non-BMP character
+    # it stands for.  These are the Python2 rules; Python3 differs.
     return runicode.unicode_encode_utf_8(
         uni, len(uni), "strict",
         errorhandler=raise_unicode_exception_encode,
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -397,7 +397,7 @@
         space = self.space
         if space.is_none(w_destructor):
             if isinstance(self, W_CDataGCP):
-                self.w_destructor = None
+                self.detach_destructor()
                 return space.w_None
             raise oefmt(space.w_TypeError,
                         "Can remove destructor only on a object "
@@ -604,6 +604,10 @@
             self.w_destructor = None
             self.space.call_function(w_destructor, self.w_original_cdata)
 
+    def detach_destructor(self):
+        self.w_destructor = None
+        self.may_unregister_rpython_finalizer(self.space)
+
 
 W_CData.typedef = TypeDef(
     '_cffi_backend.CData',
diff --git a/pypy/module/_cffi_backend/cdlopen.py b/pypy/module/_cffi_backend/cdlopen.py
--- a/pypy/module/_cffi_backend/cdlopen.py
+++ b/pypy/module/_cffi_backend/cdlopen.py
@@ -55,6 +55,7 @@
         if not libhandle:
             raise oefmt(self.ffi.w_FFIError, "library '%s' is already closed",
                         self.libname)
+        self.may_unregister_rpython_finalizer(self.ffi.space)
 
         # Clear the dict to force further accesses to do cdlopen_fetch()
         # again, and fail because the library was closed.  Note that the
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
@@ -401,7 +401,8 @@
             retries += 1
             assert retries <= 5
             import gc; gc.collect()
-        assert seen == [40, 40, raw1, raw2]
+        assert (seen == [40, 40, raw1, raw2] or
+                seen == [40, 40, raw2, raw1])
         assert repr(seen[2]) == "<cdata 'char[]' owning 41 bytes>"
         assert repr(seen[3]) == "<cdata 'char[]' owning 41 bytes>"
 
diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -1,4 +1,5 @@
 import sys
+from rpython.rlib.objectmodel import specialize
 from pypy.interpreter import gateway
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
@@ -6,7 +7,6 @@
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError, oefmt
 from rpython.rlib.debug import check_nonneg
-from rpython.rlib.objectmodel import specialize
 
 
 # A `dequeobject` is composed of a doubly-linked list of `block` nodes.
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -172,6 +172,7 @@
             self.newlines = self.stream.getnewlines()
             self.stream = None
             self.fd = -1
+            self.may_unregister_rpython_finalizer(self.space)
             openstreams = getopenstreams(self.space)
             try:
                 del openstreams[stream]
diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -233,6 +233,7 @@
         except SocketError:
             # cpython doesn't return any errors on close
             pass
+        self.may_unregister_rpython_finalizer(space)
 
     def connect_w(self, space, w_addr):
         """connect(address)
diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -217,7 +217,7 @@
             return self.space.w_None
         return w_obj
 
-    def descr__eq__(self, space, w_ref2):
+    def compare(self, space, w_ref2, invert):
         if not isinstance(w_ref2, W_Weakref):
             return space.w_NotImplemented
         ref1 = self
@@ -225,11 +225,18 @@
         w_obj1 = ref1.dereference()
         w_obj2 = ref2.dereference()
         if w_obj1 is None or w_obj2 is None:
-            return space.is_(ref1, ref2)
-        return space.eq(w_obj1, w_obj2)
+            w_res = space.is_(ref1, ref2)
+        else:
+            w_res = space.eq(w_obj1, w_obj2)
+        if invert:
+            w_res = space.not_(w_res)
+        return w_res
+
+    def descr__eq__(self, space, w_ref2):
+        return self.compare(space, w_ref2, invert=False)
 
     def descr__ne__(self, space, w_ref2):
-        return space.not_(space.eq(self, w_ref2))
+        return self.compare(space, w_ref2, invert=True)
 
 def getlifeline(space, w_obj):
     lifeline = w_obj.getweakref()
diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py
--- a/pypy/module/_weakref/test/test_weakref.py
+++ b/pypy/module/_weakref/test/test_weakref.py
@@ -150,6 +150,14 @@
         assert not (ref1 == [])
         assert ref1 != []
 
+    def test_ne(self):
+        import _weakref
+        class X(object):
+            pass
+        ref1 = _weakref.ref(X())
+        assert ref1.__eq__(X()) is NotImplemented
+        assert ref1.__ne__(X()) is NotImplemented
+
     def test_getweakrefs(self):
         import _weakref, gc
         class A(object):
diff --git a/pypy/module/cppyy/bench/Makefile b/pypy/module/cppyy/bench/Makefile
--- a/pypy/module/cppyy/bench/Makefile
+++ b/pypy/module/cppyy/bench/Makefile
@@ -26,4 +26,4 @@
 
 bench02Dict_reflex.so: bench02.h bench02.cxx bench02.xml
 	$(genreflex) bench02.h $(genreflexflags) --selection=bench02.xml -I$(ROOTSYS)/include
-	g++ -o $@ bench02.cxx bench02_rflx.cpp -I$(ROOTSYS)/include -shared -std=c++14 -lHistPainter `root-config --libs` $(cppflags) $(cppflags2)
+	g++ -o $@ bench02.cxx bench02_rflx.cpp -I$(ROOTSYS)/include -shared -std=c++11 -lHistPainter `root-config --libs` $(cppflags) $(cppflags2)
diff --git a/pypy/module/cppyy/capi/cling_capi.py b/pypy/module/cppyy/capi/cling_capi.py
--- a/pypy/module/cppyy/capi/cling_capi.py
+++ b/pypy/module/cppyy/capi/cling_capi.py
@@ -63,7 +63,7 @@
     includes=["clingcwrapper.h"],
     library_dirs=rootlibpath,
     libraries=["Cling"],
-    compile_extra=["-fno-strict-aliasing", "-std=c++14"],
+    compile_extra=["-fno-strict-aliasing", "-std=c++11"],
     use_cpp_linker=True,
 )
 
diff --git a/pypy/module/cppyy/src/dummy_backend.cxx b/pypy/module/cppyy/src/dummy_backend.cxx
--- a/pypy/module/cppyy/src/dummy_backend.cxx
+++ b/pypy/module/cppyy/src/dummy_backend.cxx
@@ -76,51 +76,66 @@
 
 static std::map<std::string, long> s_methods;
 
+int Pseudo_kNothing   = 6;
+int Pseudo_kSomething = 111;
+int Pseudo_kLots      = 42;
+
 #define PUBLIC_CPPYY_DATA(dmname, dmtype)                                     \
     data.push_back(Cppyy_PseudoDatambrInfo("m_"#dmname, #dmtype,              \
-        offsetof(dummy::cppyy_test_data, m_##dmname), false));                \
+        offsetof(dummy::CppyyTestData, m_##dmname), false));                  \
+    /* <type> get_<type>() */                                                 \
     argtypes.clear();                                                         \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
                          "get_"#dmname, argtypes, #dmtype));                  \
-    s_methods["cppyy_test_data::get_"#dmname] = s_method_id++;                \
+    s_methods["CppyyTestData::get_"#dmname] = s_method_id++;                  \
+    /* <type>& get_<type>_r() */                                              \
+    methods.push_back(Cppyy_PseudoMethodInfo(                                 \
+                         "get_"#dmname"_r", argtypes, #dmtype"&"));           \
+    s_methods["CppyyTestData::get_"#dmname"_r"] = s_method_id++;              \
+    /* const <type>& get_<type>_cr() */                                       \
+    methods.push_back(Cppyy_PseudoMethodInfo(                                 \
+                         "get_"#dmname"_cr", argtypes, "const "#dmtype"&"));  \
+    s_methods["CppyyTestData::get_"#dmname"_cr"] = s_method_id++;             \
+    /* void set_<type>(<type>) */                                             \
     argtypes.push_back(#dmtype);                                              \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
                          "set_"#dmname, argtypes, "void"));                   \
-    s_methods["cppyy_test_data::set_"#dmname] = s_method_id++;                \
+    s_methods["CppyyTestData::set_"#dmname] = s_method_id++;                  \
     argtypes.clear();                                                         \
+    /* void set_<type>(const <type>&) */                                      \
     argtypes.push_back("const "#dmtype"&");                                   \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
-                         "set_"#dmname"_c", argtypes, "void"));               \
-    s_methods["cppyy_test_data::set_"#dmname"_c"] = s_method_id++
+                         "set_"#dmname"_cr", argtypes, "void"));              \
+    s_methods["CppyyTestData::set_"#dmname"_cr"] = s_method_id++
 
 #define PUBLIC_CPPYY_DATA2(dmname, dmtype)                                    \
     PUBLIC_CPPYY_DATA(dmname, dmtype);                                        \
     data.push_back(Cppyy_PseudoDatambrInfo("m_"#dmname"_array", #dmtype"[5]", \
-        offsetof(dummy::cppyy_test_data, m_##dmname##_array), false));        \
+        offsetof(dummy::CppyyTestData, m_##dmname##_array), false));          \
     data.push_back(Cppyy_PseudoDatambrInfo("m_"#dmname"_array2", #dmtype"*",  \
-        offsetof(dummy::cppyy_test_data, m_##dmname##_array2), false));       \
+        offsetof(dummy::CppyyTestData, m_##dmname##_array2), false));         \
     argtypes.clear();                                                         \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
                          "get_"#dmname"_array", argtypes, #dmtype"*"));       \
-    s_methods["cppyy_test_data::get_"#dmname"_array"] = s_method_id++;        \
+    s_methods["CppyyTestData::get_"#dmname"_array"] = s_method_id++;          \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
                          "get_"#dmname"_array2", argtypes, #dmtype"*"));      \
-    s_methods["cppyy_test_data::get_"#dmname"_array2"] = s_method_id++
+    s_methods["CppyyTestData::get_"#dmname"_array2"] = s_method_id++
 
 #define PUBLIC_CPPYY_DATA3(dmname, dmtype, key)                               \
     PUBLIC_CPPYY_DATA2(dmname, dmtype);                                       \
     argtypes.push_back(#dmtype"*");                                           \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
                          "pass_array", argtypes, #dmtype"*"));                \
-    s_methods["cppyy_test_data::pass_array_"#dmname] = s_method_id++;         \
+    s_methods["CppyyTestData::pass_array_"#dmname] = s_method_id++;           \
     argtypes.clear(); argtypes.push_back("void*");                            \
     methods.push_back(Cppyy_PseudoMethodInfo(                                 \
                          "pass_void_array_"#key, argtypes, #dmtype"*"));      \
-    s_methods["cppyy_test_data::pass_void_array_"#key] = s_method_id++
+    s_methods["CppyyTestData::pass_void_array_"#key] = s_method_id++
 
 #define PUBLIC_CPPYY_STATIC_DATA(dmname, dmtype)                              \
     data.push_back(Cppyy_PseudoDatambrInfo("s_"#dmname, #dmtype,              \
-        (ptrdiff_t)&dummy::cppyy_test_data::s_##dmname, true))
+        (ptrdiff_t)&dummy::CppyyTestData::s_##dmname, true))
 
 
 struct Cppyy_InitPseudoReflectionInfo {
@@ -284,22 +299,23 @@
 
         //====================================================================
 
-        { // class cppyy_test_data --
-        s_handles["cppyy_test_data"] = (cppyy_scope_t)++s_scope_id;
+        { // class CppyyTestData --
+        s_handles["CppyyTestData"] = (cppyy_scope_t)++s_scope_id;
 
         std::vector<Cppyy_PseudoMethodInfo> methods;
 
-        // cppyy_test_data()
+        // CppyyTestData()
         std::vector<std::string> argtypes;
-        methods.push_back(Cppyy_PseudoMethodInfo("cppyy_test_data", argtypes, "constructor", kConstructor));
-        s_methods["cppyy_test_data::cppyy_test_data"] = s_method_id++;
+        methods.push_back(Cppyy_PseudoMethodInfo("CppyyTestData", argtypes, "constructor", kConstructor));
+        s_methods["CppyyTestData::CppyyTestData"] = s_method_id++;
 
         methods.push_back(Cppyy_PseudoMethodInfo("destroy_arrays", argtypes, "void"));
-        s_methods["cppyy_test_data::destroy_arrays"] = s_method_id++;
+        s_methods["CppyyTestData::destroy_arrays"] = s_method_id++;
 
         std::vector<Cppyy_PseudoDatambrInfo> data;
         PUBLIC_CPPYY_DATA2(bool,    bool);
         PUBLIC_CPPYY_DATA (char,    char);
+        PUBLIC_CPPYY_DATA (schar,   signed char);
         PUBLIC_CPPYY_DATA (uchar,   unsigned char);
         PUBLIC_CPPYY_DATA3(short,   short,              h);
         PUBLIC_CPPYY_DATA3(ushort,  unsigned short,     H);
@@ -309,12 +325,16 @@
         PUBLIC_CPPYY_DATA3(ulong,   unsigned long,      L);
         PUBLIC_CPPYY_DATA (llong,   long long);
         PUBLIC_CPPYY_DATA (ullong,  unsigned long long);
+        PUBLIC_CPPYY_DATA (long64,  Long64_t);
+        PUBLIC_CPPYY_DATA (ulong64, ULong64_t);
         PUBLIC_CPPYY_DATA3(float,   float,              f);
         PUBLIC_CPPYY_DATA3(double,  double,             d);
-        PUBLIC_CPPYY_DATA (enum,    cppyy_test_data::what);
+        PUBLIC_CPPYY_DATA (ldouble, long double);
+        PUBLIC_CPPYY_DATA (enum,    CppyyTestData::EWhat);
         PUBLIC_CPPYY_DATA (voidp,   void*);
 
         PUBLIC_CPPYY_STATIC_DATA(char,    char);
+        PUBLIC_CPPYY_STATIC_DATA(schar,   signed char);
         PUBLIC_CPPYY_STATIC_DATA(uchar,   unsigned char);
         PUBLIC_CPPYY_STATIC_DATA(short,   short);
         PUBLIC_CPPYY_STATIC_DATA(ushort,  unsigned short);
@@ -324,14 +344,25 @@
         PUBLIC_CPPYY_STATIC_DATA(ulong,   unsigned long);
         PUBLIC_CPPYY_STATIC_DATA(llong,   long long);
         PUBLIC_CPPYY_STATIC_DATA(ullong,  unsigned long long);
+        PUBLIC_CPPYY_STATIC_DATA(long64,  Long64_t);
+        PUBLIC_CPPYY_STATIC_DATA(ulong64, ULong64_t);
         PUBLIC_CPPYY_STATIC_DATA(float,   float);
         PUBLIC_CPPYY_STATIC_DATA(double,  double);
-        PUBLIC_CPPYY_STATIC_DATA(enum,    cppyy_test_data::what);
+        PUBLIC_CPPYY_STATIC_DATA(ldouble, long double);
+        PUBLIC_CPPYY_STATIC_DATA(enum,    CppyyTestData::EWhat);
         PUBLIC_CPPYY_STATIC_DATA(voidp,   void*);
 
+      // pretend enum values
+        data.push_back(Cppyy_PseudoDatambrInfo(
+            "kNothing", "CppyyTestData::EWhat", (ptrdiff_t)&Pseudo_kNothing, true));
+        data.push_back(Cppyy_PseudoDatambrInfo(
+            "kSomething", "CppyyTestData::EWhat", (ptrdiff_t)&Pseudo_kSomething, true));
+        data.push_back(Cppyy_PseudoDatambrInfo(
+            "kLots", "CppyyTestData::EWhat", (ptrdiff_t)&Pseudo_kLots, true));
+
         Cppyy_PseudoClassInfo info(methods, s_method_id - methods.size(), data);
         s_scopes[(cppyy_scope_t)s_scope_id] = info;
-        } // -- class cppyy_test_data
+        } // -- class CppyyTest_data
 
     }
 } _init;
@@ -385,78 +416,78 @@
     } else if (idx == s_methods["example01::setPayload_payload*"]) {
         assert(self && nargs == 1);
         ((dummy::example01*)self)->setPayload((dummy::payload*)(*(long*)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::destroy_arrays"]) {
+    } else if (idx == s_methods["CppyyTestData::destroy_arrays"]) {
         assert(self && nargs == 0);
-        ((dummy::cppyy_test_data*)self)->destroy_arrays();
-    } else if (idx == s_methods["cppyy_test_data::set_bool"]) {
+        ((dummy::CppyyTestData*)self)->destroy_arrays();
+    } else if (idx == s_methods["CppyyTestData::set_bool"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_bool((bool)((CPPYY_G__value*)args)[0].obj.i);
-    } else if (idx == s_methods["cppyy_test_data::set_char"]) {
+        ((dummy::CppyyTestData*)self)->set_bool((bool)((CPPYY_G__value*)args)[0].obj.i);
+    } else if (idx == s_methods["CppyyTestData::set_char"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_char(((CPPYY_G__value*)args)[0].obj.ch);
-    } else if (idx == s_methods["cppyy_test_data::set_uchar"]) {
+        ((dummy::CppyyTestData*)self)->set_char(((CPPYY_G__value*)args)[0].obj.ch);
+    } else if (idx == s_methods["CppyyTestData::set_uchar"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_uchar(((CPPYY_G__value*)args)[0].obj.uch);
-    } else if (idx == s_methods["cppyy_test_data::set_short"]) {
+        ((dummy::CppyyTestData*)self)->set_uchar(((CPPYY_G__value*)args)[0].obj.uch);
+    } else if (idx == s_methods["CppyyTestData::set_short"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_short(((CPPYY_G__value*)args)[0].obj.sh);
-    } else if (idx == s_methods["cppyy_test_data::set_short_c"]) {
+        ((dummy::CppyyTestData*)self)->set_short(((CPPYY_G__value*)args)[0].obj.sh);
+    } else if (idx == s_methods["CppyyTestData::set_short_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_short_c(*(short*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_ushort"]) {
+        ((dummy::CppyyTestData*)self)->set_short_cr(*(short*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_ushort"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_ushort(((CPPYY_G__value*)args)[0].obj.ush);
-    } else if (idx == s_methods["cppyy_test_data::set_ushort_c"]) {
+        ((dummy::CppyyTestData*)self)->set_ushort(((CPPYY_G__value*)args)[0].obj.ush);
+    } else if (idx == s_methods["CppyyTestData::set_ushort_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_ushort_c(*(unsigned short*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_int"]) {
+        ((dummy::CppyyTestData*)self)->set_ushort_cr(*(unsigned short*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_int"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_int(((CPPYY_G__value*)args)[0].obj.in);
-    } else if (idx == s_methods["cppyy_test_data::set_int_c"]) {
+        ((dummy::CppyyTestData*)self)->set_int(((CPPYY_G__value*)args)[0].obj.in);
+    } else if (idx == s_methods["CppyyTestData::set_int_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_int_c(*(int*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_uint"]) {
+        ((dummy::CppyyTestData*)self)->set_int_cr(*(int*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_uint"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_uint(((CPPYY_G__value*)args)[0].obj.uin);
-    } else if (idx == s_methods["cppyy_test_data::set_uint_c"]) {
+        ((dummy::CppyyTestData*)self)->set_uint(((CPPYY_G__value*)args)[0].obj.uin);
+    } else if (idx == s_methods["CppyyTestData::set_uint_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_uint_c(*(unsigned int*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_long"]) {
+        ((dummy::CppyyTestData*)self)->set_uint_cr(*(unsigned int*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_long"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_long(((CPPYY_G__value*)args)[0].obj.i);
-    } else if (idx == s_methods["cppyy_test_data::set_long_c"]) {
+        ((dummy::CppyyTestData*)self)->set_long(((CPPYY_G__value*)args)[0].obj.i);
+    } else if (idx == s_methods["CppyyTestData::set_long_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_long_c(*(long*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_ulong"]) {
+        ((dummy::CppyyTestData*)self)->set_long_cr(*(long*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_ulong"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_ulong(((CPPYY_G__value*)args)[0].obj.ulo);
-    } else if (idx == s_methods["cppyy_test_data::set_ulong_c"]) {
+        ((dummy::CppyyTestData*)self)->set_ulong(((CPPYY_G__value*)args)[0].obj.ulo);
+    } else if (idx == s_methods["CppyyTestData::set_ulong_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_ulong_c(*(unsigned long*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_llong"]) {
+        ((dummy::CppyyTestData*)self)->set_ulong_cr(*(unsigned long*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_llong"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_llong(((CPPYY_G__value*)args)[0].obj.ll);
-    } else if (idx == s_methods["cppyy_test_data::set_llong_c"]) {
+        ((dummy::CppyyTestData*)self)->set_llong(((CPPYY_G__value*)args)[0].obj.ll);
+    } else if (idx == s_methods["CppyyTestData::set_llong_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_llong_c(*(long long*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_ullong"]) {
+        ((dummy::CppyyTestData*)self)->set_llong_cr(*(long long*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_ullong"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_ullong(((CPPYY_G__value*)args)[0].obj.ull);
-    } else if (idx == s_methods["cppyy_test_data::set_ullong_c"]) {
+        ((dummy::CppyyTestData*)self)->set_ullong(((CPPYY_G__value*)args)[0].obj.ull);
+    } else if (idx == s_methods["CppyyTestData::set_ullong_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_ullong_c(*(unsigned long*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_float"]) {
+        ((dummy::CppyyTestData*)self)->set_ullong_cr(*(unsigned long*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_float"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_float(((CPPYY_G__value*)args)[0].obj.fl);
-    } else if (idx == s_methods["cppyy_test_data::set_float_c"]) {
+        ((dummy::CppyyTestData*)self)->set_float(((CPPYY_G__value*)args)[0].obj.fl);
+    } else if (idx == s_methods["CppyyTestData::set_float_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_float_c(*(float*)&((CPPYY_G__value*)args)[0]);
-    } else if (idx == s_methods["cppyy_test_data::set_double"]) {
+        ((dummy::CppyyTestData*)self)->set_float_cr(*(float*)&((CPPYY_G__value*)args)[0]);
+    } else if (idx == s_methods["CppyyTestData::set_double"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_double(((CPPYY_G__value*)args)[0].obj.d);
-    } else if (idx == s_methods["cppyy_test_data::set_double_c"]) {
+        ((dummy::CppyyTestData*)self)->set_double(((CPPYY_G__value*)args)[0].obj.d);
+    } else if (idx == s_methods["CppyyTestData::set_double_cr"]) {
         assert(self && nargs == 1);
-        ((dummy::cppyy_test_data*)self)->set_double_c(*(double*)&((CPPYY_G__value*)args)[0]);
+        ((dummy::CppyyTestData*)self)->set_double_cr(*(double*)&((CPPYY_G__value*)args)[0]);
     } else {
         assert(!"method unknown in cppyy_call_v");
     }
@@ -465,9 +496,9 @@
 unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
     unsigned char result = 0;
     const long idx = (long)method;
-    if (idx == s_methods["cppyy_test_data::get_bool"]) {
+    if (idx == s_methods["CppyyTestData::get_bool"]) {
         assert(self && nargs == 0);
-        result = (unsigned char)((dummy::cppyy_test_data*)self)->get_bool();
+        result = (unsigned char)((dummy::CppyyTestData*)self)->get_bool();
     } else {
         assert(!"method unknown in cppyy_call_b");
     }
@@ -477,12 +508,12 @@
 char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
     char result = 0;
     const long idx = (long)method;
-    if (idx == s_methods["cppyy_test_data::get_char"]) {
+    if (idx == s_methods["CppyyTestData::get_char"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_char();
-    } else if (idx == s_methods["cppyy_test_data::get_uchar"]) {
+        result = ((dummy::CppyyTestData*)self)->get_char();
+    } else if (idx == s_methods["CppyyTestData::get_uchar"]) {
         assert(self && nargs == 0);
-        result = (char)((dummy::cppyy_test_data*)self)->get_uchar();
+        result = (char)((dummy::CppyyTestData*)self)->get_uchar();
     } else {
         assert(!"method unknown in cppyy_call_c");
     } 
@@ -492,12 +523,12 @@
 short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
     short result = 0;
     const long idx = (long)method; 
-    if (idx == s_methods["cppyy_test_data::get_short"]) {
+    if (idx == s_methods["CppyyTestData::get_short"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_short();
-    } else if (idx == s_methods["cppyy_test_data::get_ushort"]) {
+        result = ((dummy::CppyyTestData*)self)->get_short();
+    } else if (idx == s_methods["CppyyTestData::get_ushort"]) {
         assert(self && nargs == 0);
-        result = (short)((dummy::cppyy_test_data*)self)->get_ushort();
+        result = (short)((dummy::CppyyTestData*)self)->get_ushort();
     } else {
         assert(!"method unknown in cppyy_call_h");
     }   
@@ -527,9 +558,9 @@
         assert(self && nargs == 1);
         result = ((dummy::example01*)self)->addDataToAtoi(
            (const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::get_int"]) {
+    } else if (idx == s_methods["CppyyTestData::get_int"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_int();
+        result = ((dummy::CppyyTestData*)self)->get_int();
     } else {
         assert(!"method unknown in cppyy_call_i");
     }
@@ -556,120 +587,120 @@
         assert(self && nargs == 1);
         result = (long)((dummy::example01*)self)->cyclePayload(
            (dummy::payload*)(*(long*)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::get_uint"]) {
+    } else if (idx == s_methods["CppyyTestData::get_uint"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_uint();
-    } else if (idx == s_methods["cppyy_test_data::get_long"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_uint();
+    } else if (idx == s_methods["CppyyTestData::get_long"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_long();
-    } else if (idx == s_methods["cppyy_test_data::get_ulong"]) {
+        result = ((dummy::CppyyTestData*)self)->get_long();
+    } else if (idx == s_methods["CppyyTestData::get_ulong"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_ulong();
-    } else if (idx == s_methods["cppyy_test_data::get_bool_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_ulong();
+    } else if (idx == s_methods["CppyyTestData::get_bool_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_bool_array();
-    } else if (idx == s_methods["cppyy_test_data::get_bool_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_bool_array();
+    } else if (idx == s_methods["CppyyTestData::get_bool_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_bool_array2();
-    } else if (idx == s_methods["cppyy_test_data::get_short_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_bool_array2();
+    } else if (idx == s_methods["CppyyTestData::get_short_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_short_array();
-    } else if (idx == s_methods["cppyy_test_data::get_short_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_short_array();
+    } else if (idx == s_methods["CppyyTestData::get_short_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_short_array2();
-    } else if (idx == s_methods["cppyy_test_data::get_ushort_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_short_array2();
+    } else if (idx == s_methods["CppyyTestData::get_ushort_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_ushort_array();
-    } else if (idx == s_methods["cppyy_test_data::get_ushort_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_ushort_array();
+    } else if (idx == s_methods["CppyyTestData::get_ushort_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_ushort_array2();
-    } else if (idx == s_methods["cppyy_test_data::get_int_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_ushort_array2();
+    } else if (idx == s_methods["CppyyTestData::get_int_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_int_array();
-    } else if (idx == s_methods["cppyy_test_data::get_int_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_int_array();
+    } else if (idx == s_methods["CppyyTestData::get_int_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_int_array2();
-    } else if (idx == s_methods["cppyy_test_data::get_uint_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_int_array2();
+    } else if (idx == s_methods["CppyyTestData::get_uint_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_uint_array();
-    } else if (idx == s_methods["cppyy_test_data::get_uint_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_uint_array();
+    } else if (idx == s_methods["CppyyTestData::get_uint_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_uint_array2();
-    } else if (idx == s_methods["cppyy_test_data::get_long_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_uint_array2();
+    } else if (idx == s_methods["CppyyTestData::get_long_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_long_array();
-    } else if (idx == s_methods["cppyy_test_data::get_long_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_long_array();
+    } else if (idx == s_methods["CppyyTestData::get_long_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_long_array2();
-    } else if (idx == s_methods["cppyy_test_data::get_ulong_array"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_long_array2();
+    } else if (idx == s_methods["CppyyTestData::get_ulong_array"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_ulong_array();
-    } else if (idx == s_methods["cppyy_test_data::get_ulong_array2"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_ulong_array();
+    } else if (idx == s_methods["CppyyTestData::get_ulong_array2"]) {
         assert(self && nargs == 0);
-        result = (long)((dummy::cppyy_test_data*)self)->get_ulong_array2();
-    } else if (idx == s_methods["cppyy_test_data::pass_array_short"]) {
+        result = (long)((dummy::CppyyTestData*)self)->get_ulong_array2();
+    } else if (idx == s_methods["CppyyTestData::pass_array_short"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(short**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_h"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_h"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_h(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_h(
            (*(short**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_ushort"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_ushort"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(unsigned short**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_H"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_H"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_H(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_H(
            (*(unsigned short**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_int"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_int"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(int**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_i"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_i"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_i(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_i(
            (*(int**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_uint"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_uint"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(unsigned int**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_I"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_I"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_I(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_I(
            (*(unsigned int**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_long"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_long"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(long**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_l"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_l"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_l(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_l(
            (*(long**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_ulong"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_ulong"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(unsigned long**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_L"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_L"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_L(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_L(
            (*(unsigned long**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_float"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_float"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(float**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_f"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_f"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_f(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_f(
            (*(float**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_array_double"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_array_double"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_array(
+        result = (long)((dummy::CppyyTestData*)self)->pass_array(
            (*(double**)&((CPPYY_G__value*)args)[0]));
-    } else if (idx == s_methods["cppyy_test_data::pass_void_array_d"]) {
+    } else if (idx == s_methods["CppyyTestData::pass_void_array_d"]) {
         assert(self && nargs == 1);
-        result = (long)((dummy::cppyy_test_data*)self)->pass_void_array_d(
+        result = (long)((dummy::CppyyTestData*)self)->pass_void_array_d(
            (*(double**)&((CPPYY_G__value*)args)[0]));
     } else {
         assert(!"method unknown in cppyy_call_l");
@@ -680,12 +711,12 @@
 long long cppyy_call_ll(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
     long long result = 0;
     const long idx = (long)method;
-    if (idx == s_methods["cppyy_test_data::get_llong"]) {
+    if (idx == s_methods["CppyyTestData::get_llong"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_llong();
-    } else if (idx == s_methods["cppyy_test_data::get_ullong"]) {
+        result = ((dummy::CppyyTestData*)self)->get_llong();
+    } else if (idx == s_methods["CppyyTestData::get_ullong"]) {
         assert(self && nargs == 0);
-        result = (long long)((dummy::cppyy_test_data*)self)->get_ullong();
+        result = (long long)((dummy::CppyyTestData*)self)->get_ullong();
     } else {
         assert(!"method unknown in cppyy_call_ll");
     }
@@ -695,9 +726,9 @@
 float cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
     float result = 0;
     const long idx = (long)method;
-    if (idx == s_methods["cppyy_test_data::get_float"]) {
+    if (idx == s_methods["CppyyTestData::get_float"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_float();
+        result = ((dummy::CppyyTestData*)self)->get_float();
     } else {
         assert(!"method unknown in cppyy_call_f");
     }
@@ -716,15 +747,48 @@
     } else if (idx == s_methods["payload::getData"]) {
         assert(self && nargs == 0);
         result = ((dummy::payload*)self)->getData();
-    } else if (idx == s_methods["cppyy_test_data::get_double"]) {
+    } else if (idx == s_methods["CppyyTestData::get_double"]) {
         assert(self && nargs == 0);
-        result = ((dummy::cppyy_test_data*)self)->get_double();
+        result = ((dummy::CppyyTestData*)self)->get_double();
     } else {
         assert(!"method unknown in cppyy_call_d");
     }
     return result;
 }
 
+#define DISPATCH_CALL_R_GET(tpname)                                           \
+    else if (idx == s_methods["CppyyTestData::get_"#tpname"_r"]) {            \
+        assert(self && nargs == 0);                                           \
+        result = (void*)&((dummy::CppyyTestData*)self)->get_##tpname##_r();   \
+    } else if (idx == s_methods["CppyyTestData::get_"#tpname"_cr"]) {         \
+        assert(self && nargs == 0);                                           \
+        result = (void*)&((dummy::CppyyTestData*)self)->get_##tpname##_cr();  \
+    }
+
+void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    void* result = nullptr;
+    const long idx = (long)method;
+    if (0) {}
+    DISPATCH_CALL_R_GET(bool)
+    DISPATCH_CALL_R_GET(short)
+    DISPATCH_CALL_R_GET(ushort)
+    DISPATCH_CALL_R_GET(int)
+    DISPATCH_CALL_R_GET(uint)
+    DISPATCH_CALL_R_GET(long)
+    DISPATCH_CALL_R_GET(ulong)
+    DISPATCH_CALL_R_GET(llong)
+    DISPATCH_CALL_R_GET(ullong)
+    DISPATCH_CALL_R_GET(long64)
+    DISPATCH_CALL_R_GET(ulong64)
+    DISPATCH_CALL_R_GET(float)
+    DISPATCH_CALL_R_GET(double)
+    DISPATCH_CALL_R_GET(ldouble)
+    else {
+        assert(!"method unknown in cppyy_call_r");
+    }
+    return result;
+}
+
 char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args, size_t* /* length */) {
     char* result = 0;
     const long idx = (long)method;
@@ -750,9 +814,9 @@
         assert(nargs == 0 || nargs == 1);
         if (nargs == 0) result = new dummy::payload;
         else if (nargs == 1) result = new dummy::payload(((CPPYY_G__value*)args)[0].obj.d);
-    } else if (idx == s_methods["cppyy_test_data::cppyy_test_data"]) {
+    } else if (idx == s_methods["CppyyTestData::CppyyTestData"]) {
         assert(nargs == 0);
-        result = new dummy::cppyy_test_data;
+        result = new dummy::CppyyTestData;
     } else {
         assert(!"method unknown in cppyy_constructor");
     }       
@@ -792,11 +856,17 @@
     return 0;
 }
 
+int cppyy_is_template(const char* /* template_name */) {
+    return 0;
+}
+
 int cppyy_is_abstract(cppyy_type_t /* type) */) {
     return 0;
 }
 
-int cppyy_is_enum(const char* /* type_name */) {
+int cppyy_is_enum(const char* type_name) {
+    if (strcmp(type_name, "CppyyTestData::EWhat") == 0)
+        return 1;
     return 0;
 }
     
diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile
--- a/pypy/module/cppyy/test/Makefile
+++ b/pypy/module/cppyy/test/Makefile
@@ -29,7 +29,7 @@
 endif
 
 ifeq ($(DUMMY),t)
-  cppflags2=-O3 -fPIC -rdynamic
+  cppflags2=-O3 -fPIC -rdynamic -std=c++11 -DCPPYY_DUMMY_BACKEND
 else ifeq ($(CLING),t)
   cppflags2=-O3 -fPIC -rdynamic
 else
@@ -55,7 +55,7 @@
 
 else # reflex
 %Dict.so: %_rflx.cpp %.cxx
-	g++ -o $@ $^ -shared -std=c++14 $(cppflags) $(cppflags2)
+	g++ -o $@ $^ -shared $(cppflags) $(cppflags2)
 
 %_rflx.cpp: %.h %.xml
 	$(genreflex) $< $(genreflexflags) --selection=$*.xml --rootmap=$*Dict.rootmap --rootmap-lib=$*Dict.so
@@ -66,7 +66,7 @@
 # TODO: methptrgetter causes these tests to crash, so don't use it for now
 std_streamsDict.so: std_streams.cxx std_streams.h std_streams.xml
 	$(genreflex) std_streams.h --selection=std_streams.xml
-	g++ -o $@ std_streams_rflx.cpp std_streams.cxx -shared -std=c++14 $(cppflags) $(cppflags2)
+	g++ -o $@ std_streams_rflx.cpp std_streams.cxx -shared -std=c++11 $(cppflags) $(cppflags2)
 endif
 
 .PHONY: clean
diff --git a/pypy/module/cppyy/test/conftest.py b/pypy/module/cppyy/test/conftest.py
--- a/pypy/module/cppyy/test/conftest.py
+++ b/pypy/module/cppyy/test/conftest.py
@@ -50,7 +50,8 @@
             eci = ExternalCompilationInfo(
                 separate_module_files=[srcpath.join('dummy_backend.cxx')],
                 include_dirs=[incpath, tstpath, cdir],
-                compile_extra=['-DRPY_EXTERN=RPY_EXPORTED'],
+                compile_extra=['-DRPY_EXTERN=RPY_EXPORTED', '-DCPPYY_DUMMY_BACKEND',
+                               '-fno-strict-aliasing', '-std=c++11'],
                 use_cpp_linker=True,
             )
 
diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h
--- a/pypy/module/cppyy/test/datatypes.h
+++ b/pypy/module/cppyy/test/datatypes.h
@@ -1,4 +1,15 @@
+#ifndef CPPYY_DUMMY_BACKEND
 #include "RtypesCore.h"
+#else
+// copied from RtypesCore.h ...
+#if defined(R__WIN32) && !defined(__CINT__)
+typedef __int64          Long64_t;  //Portable signed long integer 8 bytes
+typedef unsigned __int64 ULong64_t; //Portable unsigned long integer 8 bytes
+#else
+typedef long long          Long64_t; //Portable signed long integer 8 bytes
+typedef unsigned long long ULong64_t;//Portable unsigned long integer 8 bytes
+#endif
+#endif
 #include <vector>
 
 const int N = 5;
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -157,13 +157,13 @@
         assert isinstance(w_obj, FakeFloat)
         return w_obj.val
 
+    @specialize.arg(1)
     def interp_w(self, RequiredClass, w_obj, can_be_None=False):
         if can_be_None and w_obj is None:
             return None
         if not isinstance(w_obj, RequiredClass):
             raise TypeError
         return w_obj
-    interp_w._annspecialcase_ = 'specialize:arg(1)'
 
     def getarg_w(self, code, w_obj):    # for retrieving buffers
         return FakeBuffer(w_obj)
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -36,8 +36,6 @@
 from rpython.rlib.objectmodel import specialize
 from pypy.module import exceptions
 from pypy.module.exceptions import interp_exceptions
-# CPython 2.4 compatibility
-from py.builtin import BaseException
 from rpython.tool.sourcetools import func_with_new_name
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rlib import rawrefcount
@@ -985,7 +983,7 @@
         py_type_ready(space, get_capsule_type())
     INIT_FUNCTIONS.append(init_types)
     from pypy.module.posix.interp_posix import add_fork_hook
-    _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [], 
+    _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [],
                                   lltype.Void, compilation_info=eci)
     def reinit_tls(space):
         _reinit_tls()
@@ -1614,9 +1612,8 @@
     miniglobals = {'__name__':    __name__, # for module name propagation
                    }
     exec source.compile() in miniglobals
-    call_external_function = miniglobals['cpy_call_external']
+    call_external_function = specialize.ll()(miniglobals['cpy_call_external'])
     call_external_function._dont_inline_ = True
-    call_external_function._annspecialcase_ = 'specialize:ll'
     call_external_function._gctransformer_hint_close_stack_ = True
     # don't inline, as a hack to guarantee that no GC pointer is alive
     # anywhere in call_external_function
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -137,8 +137,7 @@
     """This is the same as PyDict_Merge(a, b, 1) in C, or a.update(b) in
     Python.  Return 0 on success or -1 if an exception was raised.
     """
-    space.call_method(space.w_dict, "update", w_obj, w_other)
-    return 0
+    return PyDict_Merge(space, w_obj, w_other, 1)
 
 @cpython_api([PyObject], PyObject)
 def PyDict_Keys(space, w_obj):
diff --git a/pypy/module/cpyext/listobject.py b/pypy/module/cpyext/listobject.py
--- a/pypy/module/cpyext/listobject.py
+++ b/pypy/module/cpyext/listobject.py
@@ -62,12 +62,14 @@
     position must be positive, indexing from the end of the list is not
     supported.  If pos is out of bounds, return NULL and set an
     IndexError exception."""
+    from pypy.module.cpyext.sequence import CPyListStrategy
     if not isinstance(w_list, W_ListObject):
         PyErr_BadInternalCall(space)
     if index < 0 or index >= w_list.length():
         raise oefmt(space.w_IndexError, "list index out of range")
-    w_list.ensure_object_strategy()  # make sure we can return a borrowed obj
-    # XXX ^^^ how does this interact with CPyListStrategy?
+    cpy_strategy = space.fromcache(CPyListStrategy)
+    if w_list.strategy is not cpy_strategy:
+        w_list.ensure_object_strategy() # make sure we can return a borrowed obj
     w_res = w_list.getitem(index)
     return w_res     # borrowed ref
 
diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py
--- a/pypy/module/cpyext/modsupport.py
+++ b/pypy/module/cpyext/modsupport.py
@@ -1,7 +1,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import cpython_api, cpython_struct, \
         METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, CONST_STRING
-from pypy.module.cpyext.pyobject import PyObject
+from pypy.module.cpyext.pyobject import PyObject, as_pyobj
 from pypy.interpreter.module import Module
 from pypy.module.cpyext.methodobject import (
     W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod,
@@ -124,11 +124,17 @@
     else:
         PyErr_BadInternalCall(space)
 
- at cpython_api([PyObject], rffi.CCHARP, error=0)
-def PyModule_GetName(space, module):
+ at cpython_api([PyObject], rffi.CCHARP)
+def PyModule_GetName(space, w_mod):
     """
     Return module's __name__ value.  If the module does not provide one,
-    or if it is not a string, SystemError is raised and NULL is returned."""
-    raise NotImplementedError
-
-
+    or if it is not a string, SystemError is raised and NULL is returned.
+    """
+    # NOTE: this version of the code works only because w_mod.w_name is
+    # a wrapped string object attached to w_mod; so it makes a
+    # PyStringObject that will live as long as the module itself,
+    # and returns a "char *" inside this PyStringObject.
+    if not isinstance(w_mod, Module):
+        raise oefmt(space.w_SystemError, "PyModule_GetName(): not a module")
+    from pypy.module.cpyext.bytesobject import PyString_AsString
+    return PyString_AsString(space, as_pyobj(space, w_mod.w_name))
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -15,6 +15,7 @@
 from rpython.rlib.objectmodel import keepalive_until_here
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.rlib import rawrefcount
+from rpython.rlib.debug import fatalerror
 
 
 #________________________________________________________
@@ -24,11 +25,9 @@
     basestruct = PyObject.TO
     W_BaseObject = W_ObjectObject
 
-    def get_dealloc(self, space):
+    def get_dealloc(self):
         from pypy.module.cpyext.typeobject import subtype_dealloc
-        return llhelper(
-            subtype_dealloc.api_func.functype,
-            subtype_dealloc.api_func.get_wrapper(space))
+        return subtype_dealloc.api_func
 
     def allocate(self, space, w_type, itemcount=0):
         # similar to PyType_GenericAlloc?
@@ -108,10 +107,8 @@
                 return tp_alloc(space, w_type, itemcount)
 
         if tp_dealloc:
-            def get_dealloc(self, space):
-                return llhelper(
-                    tp_dealloc.api_func.functype,
-                    tp_dealloc.api_func.get_wrapper(space))
+            def get_dealloc(self):
+                return tp_dealloc.api_func
 
         if tp_attach:
             def attach(self, space, pyobj, w_obj):
@@ -192,6 +189,8 @@
     rawrefcount.create_link_pypy(w_obj, py_obj)
 
 
+w_marker_deallocating = W_Root()
+
 def from_ref(space, ref):
     """
     Finds the interpreter object corresponding to the given reference.  If the
@@ -202,7 +201,23 @@
         return None
     w_obj = rawrefcount.to_obj(W_Root, ref)
     if w_obj is not None:
-        return w_obj
+        if w_obj is not w_marker_deallocating:
+            return w_obj
+        fatalerror(
+            "*** Invalid usage of a dying CPython object ***\n"
+            "\n"
+            "cpyext, the emulation layer, detected that while it is calling\n"
+            "an object's tp_dealloc, the C code calls back a function that\n"
+            "tries to recreate the PyPy version of the object.  Usually it\n"
+            "means that tp_dealloc calls some general PyXxx() API.  It is\n"
+            "a dangerous and potentially buggy thing to do: even in CPython\n"
+            "the PyXxx() function could, in theory, cause a reference to the\n"
+            "object to be taken and stored somewhere, for an amount of time\n"
+            "exceeding tp_dealloc itself.  Afterwards, the object will be\n"
+            "freed, making that reference point to garbage.\n"
+            ">>> PyPy could contain some workaround to still work if\n"
+            "you are lucky, but it is not done so far; better fix the bug in\n"
+            "the CPython extension.")
 
     # This reference is not yet a real interpreter object.
     # Realize it.
@@ -233,7 +248,8 @@
 INTERPLEVEL_API['as_pyobj'] = as_pyobj
 
 def pyobj_has_w_obj(pyobj):
-    return rawrefcount.to_obj(W_Root, pyobj) is not None
+    w_obj = rawrefcount.to_obj(W_Root, pyobj)
+    return w_obj is not None and w_obj is not w_marker_deallocating
 INTERPLEVEL_API['pyobj_has_w_obj'] = staticmethod(pyobj_has_w_obj)
 
 
@@ -335,6 +351,7 @@
     pto = obj.c_ob_type
     #print >>sys.stderr, "Calling dealloc slot", pto.c_tp_dealloc, "of", obj, \
     #      "'s type which is", rffi.charp2str(pto.c_tp_name)
+    rawrefcount.mark_deallocating(w_marker_deallocating, obj)
     generic_cpy_call(space, pto.c_tp_dealloc, obj)
 
 @cpython_api([rffi.VOIDP], lltype.Signed, error=CANNOT_FAIL)
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -8,12 +8,12 @@
     cpython_api, generic_cpy_call, PyObject, Py_ssize_t, Py_TPFLAGS_CHECKTYPES,
     mangle_name, pypy_decl, Py_buffer, Py_bufferP)
 from pypy.module.cpyext.typeobjectdefs import (
-    unaryfunc, wrapperfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc, ternaryfunc,
+    unaryfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc,
     getattrfunc, getattrofunc, setattrofunc, lenfunc, ssizeargfunc, inquiry,
     ssizessizeargfunc, ssizeobjargproc, iternextfunc, initproc, richcmpfunc,
     cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, objobjargproc,
     readbufferproc, getbufferproc, ssizessizeobjargproc)
-from pypy.module.cpyext.pyobject import from_ref, make_ref, Py_DecRef
+from pypy.module.cpyext.pyobject import make_ref, Py_DecRef
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.module.cpyext.memoryobject import fill_Py_buffer
 from pypy.module.cpyext.state import State
@@ -21,8 +21,10 @@
 from pypy.interpreter.argument import Arguments
 from rpython.rlib.buffer import Buffer
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, not_rpython
 from rpython.tool.sourcetools import func_renamer
+from rpython.flowspace.model import Constant
+from rpython.flowspace.specialcase import register_flow_sc
 from rpython.rtyper.annlowlevel import llhelper
 from pypy.module.sys.version import CPYTHON_VERSION
 
@@ -59,6 +61,17 @@
                 "expected %d-%d arguments, got %d",
                 low, high, space.len_w(w_ob))
 
+ at not_rpython
+def llslot(space, func):
+    return llhelper(func.api_func.functype, func.api_func.get_wrapper(space))
+
+ at register_flow_sc(llslot)
+def sc_llslot(ctx, v_space, v_func):
+    assert isinstance(v_func, Constant)
+    get_llhelper = v_func.value.api_func.get_llhelper
+    return ctx.appcall(get_llhelper, v_space)
+
+
 def wrap_init(space, w_self, w_args, func, w_kwargs):
     func_init = rffi.cast(initproc, func)
     res = generic_cpy_call(space, func_init, w_self, w_args, w_kwargs)
@@ -106,7 +119,7 @@
     args_w = space.fixedview(w_args)
     arg3 = space.w_None
     if len(args_w) > 1:
-        arg3 = args_w[1] 
+        arg3 = args_w[1]
     return generic_cpy_call(space, func_ternary, w_self, args_w[0], arg3)
 
 def wrap_ternaryfunc_r(space, w_self, w_args, func):
@@ -121,7 +134,7 @@
     Py_DecRef(space, ref)
     arg3 = space.w_None
     if len(args_w) > 1:
-        arg3 = args_w[1] 
+        arg3 = args_w[1]
     return generic_cpy_call(space, func_ternary, args_w[0], w_self, arg3)
 
 
@@ -322,7 +335,7 @@
             self.strides = [1]
         else:
             self.strides = strides
-        self.ndim = ndim 
+        self.ndim = ndim
         self.itemsize = itemsize
         self.readonly = readonly
 
@@ -437,9 +450,10 @@
     try:
         return SLOTS[key]
     except KeyError:
-        ret = build_slot_tp_function(space, typedef, name)
-        SLOTS[key] = ret
-        return ret
+        slot_func = build_slot_tp_function(space, typedef, name)
+        api_func = slot_func.api_func if slot_func else None
+        SLOTS[key] = api_func
+        return api_func
 
 def build_slot_tp_function(space, typedef, name):
     w_type = space.gettypeobject(typedef)
@@ -472,7 +486,6 @@
             @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
             def slot_func(space, w_self):
                 return space.call_function(slot_fn, w_self)
-            api_func = slot_func.api_func
             handled = True
 
     # binary functions
@@ -499,7 +512,6 @@
             @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
             def slot_func(space, w_self, w_arg):
                 return space.call_function(slot_fn, w_self, w_arg)
-            api_func = slot_func.api_func
             handled = True
 
     # binary-with-Py_ssize_t-type
@@ -517,7 +529,6 @@
             @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
             def slot_func(space, w_self, arg):
                 return space.call_function(slot_fn, w_self, space.wrap(arg))
-            api_func = slot_func.api_func
             handled = True
 
     # ternary functions
@@ -532,7 +543,6 @@
             @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
             def slot_func(space, w_self, w_arg1, w_arg2):
                 return space.call_function(slot_fn, w_self, w_arg1, w_arg2)
-            api_func = slot_func.api_func
             handled = True
 
     if handled:
@@ -552,7 +562,7 @@
             else:
                 space.call_function(delattr_fn, w_self, w_name)
             return 0
-        api_func = slot_tp_setattro.api_func
+        slot_func = slot_tp_setattro
     elif name == 'tp_getattro':
         getattr_fn = w_type.getdictvalue(space, '__getattribute__')
         if getattr_fn is None:
@@ -562,7 +572,7 @@
         @func_renamer("cpyext_tp_getattro_%s" % (typedef.name,))
         def slot_tp_getattro(space, w_self, w_name):
             return space.call_function(getattr_fn, w_self, w_name)
-        api_func = slot_tp_getattro.api_func
+        slot_func = slot_tp_getattro
     elif name == 'tp_call':
         call_fn = w_type.getdictvalue(space, '__call__')
         if call_fn is None:
@@ -574,7 +584,7 @@
             args = Arguments(space, [w_self],
                              w_stararg=w_args, w_starstararg=w_kwds)
             return space.call_args(call_fn, args)
-        api_func = slot_tp_call.api_func
+        slot_func = slot_tp_call
 
     elif name == 'tp_iternext':
         iternext_fn = w_type.getdictvalue(space, 'next')
@@ -590,7 +600,7 @@
                 if not e.match(space, space.w_StopIteration):
                     raise
                 return None
-        api_func = slot_tp_iternext.api_func
+        slot_func = slot_tp_iternext
 
     elif name == 'tp_init':
         init_fn = w_type.getdictvalue(space, '__init__')
@@ -605,7 +615,7 @@
                              w_stararg=w_args, w_starstararg=w_kwds)
             space.call_args(init_fn, args)
             return 0
-        api_func = slot_tp_init.api_func
+        slot_func = slot_tp_init
     elif name == 'tp_new':
         new_fn = w_type.getdictvalue(space, '__new__')
         if new_fn is None:
@@ -617,12 +627,12 @@
             args = Arguments(space, [w_self],
                              w_stararg=w_args, w_starstararg=w_kwds)
             return space.call_args(space.get(new_fn, w_self), args)
-        api_func = slot_tp_new.api_func
+        slot_func = slot_tp_new
     elif name == 'tp_as_buffer.c_bf_getbuffer':
         buff_fn = w_type.getdictvalue(space, '__buffer__')
         if buff_fn is None:
             return
-        @cpython_api([PyObject, Py_bufferP, rffi.INT_real], 
+        @cpython_api([PyObject, Py_bufferP, rffi.INT_real],
                 rffi.INT_real, header=None, error=-1)
         @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
         def buff_w(space, w_self, view, flags):
@@ -646,14 +656,14 @@
             return 0
         # XXX remove this when it no longer crashes a translated PyPy
         return
-        api_func = buff_w.api_func
+        slot_func = buff_w
     else:
         # missing: tp_as_number.nb_nonzero, tp_as_number.nb_coerce
         # tp_as_sequence.c_sq_contains, tp_as_sequence.c_sq_length
         # richcmpfunc(s)
         return
 
-    return lambda: llhelper(api_func.functype, api_func.get_wrapper(space))
+    return slot_func
 
 PyWrapperFlag_KEYWORDS = 1
 
@@ -984,8 +994,8 @@
 slotdefs = sorted(slotdefs, key=slotdef_sort_key)
 
 slotdefs_for_tp_slots = unrolling_iterable(
-    [(x.method_name, x.slot_name, x.slot_names, x.slot_func)
-     for x in slotdefs])
+    [(x.method_name, x.slot_name, x.slot_names,
+      x.slot_func.api_func if x.slot_func else None) for x in slotdefs])
 
 slotdefs_for_wrappers = unrolling_iterable(
     [(x.method_name, x.slot_names, x.wrapper_func, x.wrapper_func_kwds, x.doc)
diff --git a/pypy/module/cpyext/test/test_dictobject.py b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py


More information about the pypy-commit mailing list