[pypy-commit] pypy cpyext-nowrapper: copy&adapt state.C from the branch cpyext-avoid-roundtrip, to be able to directly call functions defined in C; improve _PyObject_NewVar to compare tp directly with PyType_Type, without passing through the space

antocuni pypy.commits at gmail.com
Sat Oct 7 09:11:33 EDT 2017


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: cpyext-nowrapper
Changeset: r92629:9c8e90ccce77
Date: 2017-10-07 12:33 +0200
http://bitbucket.org/pypy/pypy/changeset/9c8e90ccce77/

Log:	copy&adapt state.C from the branch cpyext-avoid-roundtrip, to be
	able to directly call functions defined in C; improve
	_PyObject_NewVar to compare tp directly with PyType_Type, without
	passing through the space

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
@@ -1108,6 +1108,14 @@
         _reinit_tls()
     add_fork_hook('child', reinit_tls)
 
+
+def attach_c_functions(space, eci, prefix):
+    state = space.fromcache(State)
+    state.C._PyPy_get_PyType_Type = rffi.llexternal(
+        '_PyPy_get_PyType_Type', [], PyTypeObjectPtr,
+        compilation_info=eci, _nowrapper=True)
+
+
 def init_function(func):
     INIT_FUNCTIONS.append(func)
     return func
@@ -1176,6 +1184,7 @@
     space.fromcache(State).install_dll(eci)
     modulename = py.path.local(eci.libraries[-1])
 
+    attach_c_functions(space, eci, prefix)
     run_bootstrap_functions(space)
 
     # load the bridge, and init structure
@@ -1419,6 +1428,7 @@
                          source_dir / "pythread.c",
                          source_dir / "missing.c",
                          source_dir / "pymem.c",
+                         source_dir / "typeobject.c",
                          ]
 
 def build_eci(code, use_micronumpy=False, translating=False):
@@ -1513,6 +1523,7 @@
     eci = build_eci(code, use_micronumpy, translating=True)
     space.fromcache(State).install_dll(eci)
 
+    attach_c_functions(space, eci, prefix)
     run_bootstrap_functions(space)
 
     # emit uninitialized static data
diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -330,7 +330,7 @@
 PyAPI_FUNC(int) PyPyType_Register(PyTypeObject *);
 #define PyObject_Length PyObject_Size
 #define _PyObject_GC_Del PyObject_GC_Del
-
+PyAPI_FUNC(PyTypeObject*) _PyPy_get_PyType_Type(void);
 
 #ifdef __cplusplus
 }
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
@@ -9,6 +9,7 @@
     get_typedescr)
 from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 from pypy.module.cpyext.pyerrors import PyErr_NoMemory, PyErr_BadInternalCall
+from pypy.module.cpyext.state import State
 from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.interpreter.error import OperationError, oefmt
 import pypy.module.__builtin__.operation as operation
@@ -50,11 +51,10 @@
 @cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True)
 def _PyObject_NewVar(space, tp, nitems):
     from pypy.module.cpyext.pyobject import _allocate_generic_object
-    
-    w_type = from_ref(space, rffi.cast(PyObject, tp))
-    assert isinstance(w_type, W_TypeObject)
-    if w_type is space.w_type:
-        # XXX: integrate this logic with the one below
+    state = space.fromcache(State)
+    if tp is state.C._PyPy_get_PyType_Type():
+        w_type = from_ref(space, rffi.cast(PyObject, tp))
+        assert isinstance(w_type, W_TypeObject)
         typedescr = get_typedescr(w_type.layout.typedef)
         pyobj = typedescr.allocate(space, w_type, itemcount=nitems)
     else:
diff --git a/pypy/module/cpyext/src/typeobject.c b/pypy/module/cpyext/src/typeobject.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/src/typeobject.c
@@ -0,0 +1,7 @@
+#include "Python.h"
+
+PyTypeObject*
+_PyPy_get_PyType_Type(void)
+{
+    return &PyType_Type;
+}
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -14,6 +14,7 @@
         self.programname = lltype.nullptr(rffi.CCHARP.TO)
         self.version = lltype.nullptr(rffi.CCHARP.TO)
         self.builder = None
+        self.C = CNamespace()
 
     def reset(self):
         from pypy.module.cpyext.modsupport import PyMethodDef
@@ -168,6 +169,11 @@
         return w_mod
 
 
+class CNamespace:
+    def _freeze_(self):
+        return True
+
+
 def _rawrefcount_perform(space):
     from pypy.module.cpyext.pyobject import PyObject, decref
     while True:


More information about the pypy-commit mailing list