[pypy-commit] pypy py3.5: Implement PyModule_GetState()

arigo pypy.commits at gmail.com
Sun May 14 11:25:32 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r91278:11e536df3c51
Date: 2017-05-14 17:24 +0200
http://bitbucket.org/pypy/pypy/changeset/11e536df3c51/

Log:	Implement PyModule_GetState()

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
@@ -565,7 +565,7 @@
     'PyUnicode_FromFormat', 'PyUnicode_FromFormatV', 'PyUnicode_AsWideCharString',
     'PyUnicode_GetSize', 'PyUnicode_GetLength',
     'PyModule_AddObject', 'PyModule_AddIntConstant', 'PyModule_AddStringConstant',
-    'PyModule_GetDef', 'PyModuleDef_Init',
+    'PyModule_GetDef', 'PyModuleDef_Init', 'PyModule_GetState',
     'Py_BuildValue', 'Py_VaBuildValue', 'PyTuple_Pack',
     '_PyArg_Parse_SizeT', '_PyArg_ParseTuple_SizeT',
     '_PyArg_ParseTupleAndKeywords_SizeT', '_PyArg_VaParse_SizeT',
diff --git a/pypy/module/cpyext/include/modsupport.h b/pypy/module/cpyext/include/modsupport.h
--- a/pypy/module/cpyext/include/modsupport.h
+++ b/pypy/module/cpyext/include/modsupport.h
@@ -71,6 +71,7 @@
 #define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c)
 
 PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*);
+PyAPI_FUNC(void*) PyModule_GetState(PyObject*);
 
 
 PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...);
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, METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, cts,
-    parse_dir, bootstrap_function, generic_cpy_call)
+    parse_dir, bootstrap_function, generic_cpy_call, slot_function)
 from pypy.module.cpyext.pyobject import PyObject, as_pyobj, make_typedescr
 from pypy.interpreter.module import Module
 from pypy.module.cpyext.methodobject import (
@@ -18,7 +18,16 @@
 
 @bootstrap_function
 def init_moduleobject(space):
-    make_typedescr(Module.typedef, basestruct=PyModuleObject.TO)
+    make_typedescr(Module.typedef, basestruct=PyModuleObject.TO,
+                   dealloc=module_dealloc)
+
+ at slot_function([PyObject], lltype.Void)
+def module_dealloc(space, py_obj):
+    py_module = rffi.cast(PyModuleObject, py_obj)
+    if py_module.c_md_state:
+        lltype.free(py_module.c_md_state, flavor='raw')
+    from pypy.module.cpyext.object import _dealloc
+    _dealloc(space, py_obj)
 
 @cpython_api([rffi.CCHARP], PyObject)
 def PyModule_New(space, name):
@@ -49,7 +58,8 @@
     if f_name is not None:
         modname = f_name
     w_mod = Module(space, space.newtext(modname))
-    rffi.cast(PyModuleObject, as_pyobj(space, w_mod)).c_md_def = module
+    py_mod = rffi.cast(PyModuleObject, as_pyobj(space, w_mod))
+    py_mod.c_md_def = module
     state.package_context = None, None
 
     if f_path is not None:
@@ -62,6 +72,10 @@
     if doc:
         space.setattr(w_mod, space.newtext("__doc__"),
                       space.newtext(doc))
+
+    if module.c_m_size > 0:
+        py_mod.c_md_state = lltype.malloc(rffi.VOIDP.TO, module.c_m_size,
+                                          flavor='raw', zero=True)
     return w_mod
 
 
diff --git a/pypy/module/cpyext/parse/cpyext_moduleobject.h b/pypy/module/cpyext/parse/cpyext_moduleobject.h
--- a/pypy/module/cpyext/parse/cpyext_moduleobject.h
+++ b/pypy/module/cpyext/parse/cpyext_moduleobject.h
@@ -40,5 +40,5 @@
 typedef struct {
     PyObject_HEAD
     struct PyModuleDef *md_def;
-    //void *md_state;
+    void *md_state;
 } PyModuleObject;
diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c
--- a/pypy/module/cpyext/src/modsupport.c
+++ b/pypy/module/cpyext/src/modsupport.c
@@ -603,6 +603,16 @@
     return ((PyModuleObject *)m)->md_def;
 }
 
+void*
+PyModule_GetState(PyObject* m)
+{
+    if (!PyModule_Check(m)) {
+        PyErr_BadArgument();
+        return NULL;
+    }
+    return ((PyModuleObject *)m)->md_state;
+}
+
 PyTypeObject PyModuleDef_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     "moduledef",                                /* tp_name */
diff --git a/pypy/module/cpyext/test/test_module.py b/pypy/module/cpyext/test/test_module.py
--- a/pypy/module/cpyext/test/test_module.py
+++ b/pypy/module/cpyext/test/test_module.py
@@ -32,6 +32,29 @@
             """)
         assert module.check_getdef_same()
 
+    def test_getstate(self):
+        module = self.import_extension('foo', [
+            ("check_mod_getstate", "METH_NOARGS",
+             """
+                 struct module_state { int foo[51200]; };
+                 static struct PyModuleDef moduledef = {
+                     PyModuleDef_HEAD_INIT,
+                     "module_getstate_myextension",
+                     NULL,
+                     sizeof(struct module_state)
+                 };
+                 PyObject *module = PyModule_Create(&moduledef);
+                 int *p = (int *)PyModule_GetState(module);
+                 int i;
+                 for (i = 0; i < 51200; i++)
+                     if (p[i] != 0)
+                         return PyBool_FromLong(0);
+                 Py_DECREF(module);
+                 return PyBool_FromLong(1);
+             """
+            )])
+        assert module.check_mod_getstate()
+
 
 class AppTestMultiPhase(AppTestCpythonExtensionBase):
     def test_basic(self):


More information about the pypy-commit mailing list