[pypy-commit] pypy cpyext-nowrapper: Add a way to remove all wrappers around cpyext functions

rlamy pypy.commits at gmail.com
Mon Oct 2 13:02:57 EDT 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: cpyext-nowrapper
Changeset: r92559:ef509cae3c70
Date: 2017-10-02 19:02 +0200
http://bitbucket.org/pypy/pypy/changeset/ef509cae3c70/

Log:	Add a way to remove all wrappers around cpyext functions

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
@@ -258,7 +258,8 @@
 class ApiFunction(object):
     def __init__(self, argtypes, restype, callable, error=CANNOT_FAIL,
                  c_name=None, cdecl=None, gil=None,
-                 result_borrowed=False, result_is_ll=False):
+                 result_borrowed=False, result_is_ll=False,
+                 nowrapper=False):
         self.argtypes = argtypes
         self.restype = restype
         self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
@@ -270,8 +271,11 @@
         # extract the signature from the (CPython-level) code object
         from pypy.interpreter import pycode
         sig = pycode.cpython_code_signature(callable.func_code)
-        assert sig.argnames[0] == 'space'
-        self.argnames = sig.argnames[1:]
+        if nowrapper:
+            self.argnames = sig.argnames
+        else:
+            assert sig.argnames[0] == 'space'
+            self.argnames = sig.argnames[1:]
         if gil == 'pygilstate_ensure':
             assert self.argnames[-1] == 'previous_state'
             del self.argnames[-1]
@@ -280,6 +284,7 @@
         self.gil = gil
         self.result_borrowed = result_borrowed
         self.result_is_ll = result_is_ll
+        self.nowrapper = nowrapper
         #
         def get_llhelper(space):
             return llhelper(self.functype, self.get_wrapper(space))
@@ -301,6 +306,8 @@
         # This logic is obscure, because we try to avoid creating one
         # big wrapper() function for every callable.  Instead we create
         # only one per "signature".
+        if self.nowrapper:
+            return self.callable
 
         argtypesw = zip(self.argtypes,
                         [_name.startswith("w_") for _name in self.argnames])
@@ -432,7 +439,8 @@
 
 DEFAULT_HEADER = 'pypy_decl.h'
 def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER,
-                gil=None, result_borrowed=False, result_is_ll=False):
+                gil=None, result_borrowed=False, result_is_ll=False,
+                nowrapper=False):
     """
     Declares a function to be exported.
     - `argtypes`, `restype` are lltypes and describe the function signature.
@@ -457,7 +465,8 @@
         api_function = ApiFunction(
             argtypes, restype, func,
             error=_compute_error(error, restype), gil=gil,
-            result_borrowed=result_borrowed, result_is_ll=result_is_ll)
+            result_borrowed=result_borrowed, result_is_ll=result_is_ll,
+            nowrapper=nowrapper)
         FUNCTIONS_BY_HEADER[header][func.__name__] = api_function
         unwrapper = api_function.get_unwrapper()
         unwrapper.func = func
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -32,8 +32,8 @@
     # XXX FIXME
     return realloc(ptr, size)
 
- at cpython_api([rffi.VOIDP], lltype.Void)
-def PyObject_Free(space, ptr):
+ at cpython_api([rffi.VOIDP], lltype.Void, nowrapper=True)
+def PyObject_Free(ptr):
     lltype.free(ptr, flavor='raw')
 
 @cpython_api([PyTypeObjectPtr], PyObject, result_is_ll=True)
@@ -302,7 +302,7 @@
         if opid == Py_EQ:
             return 1
         if opid == Py_NE:
-            return 0 
+            return 0
     w_res = PyObject_RichCompare(space, w_o1, w_o2, opid_int)
     return int(space.is_true(w_res))
 


More information about the pypy-commit mailing list