diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst new file mode 100644 index 00000000000..cb849fb9b44 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst @@ -0,0 +1 @@ +Port :mod:`mmap` to multiphase initialization. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 8a60db1e1c4..463bd40e78f 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1509,157 +1509,163 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } #endif /* MS_WINDOWS */ -static void -setint(PyObject *d, const char *name, long value) +static int +mmap_exec(PyObject *module) { - PyObject *o = PyLong_FromLong(value); - if (o) { - PyDict_SetItemString(d, name, o); - Py_DECREF(o); + if (PyType_Ready(&mmap_object_type) < 0) { + return -1; } + + Py_INCREF(PyExc_OSError); + if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { + Py_DECREF(PyExc_OSError); + return -1; + } + if (PyModule_AddType(module, &mmap_object_type) < 0) { + return -1; + } + +#define ADD_INT_MACRO(module, constant) \ + do { \ + if (PyModule_AddIntConstant(module, #constant, constant) < 0) { \ + return -1; \ + } \ + } while (0) + +#ifdef PROT_EXEC + ADD_INT_MACRO(module, PROT_EXEC); +#endif +#ifdef PROT_READ + ADD_INT_MACRO(module, PROT_READ); +#endif +#ifdef PROT_WRITE + ADD_INT_MACRO(module, PROT_WRITE); +#endif + +#ifdef MAP_SHARED + ADD_INT_MACRO(module, MAP_SHARED); +#endif +#ifdef MAP_PRIVATE + ADD_INT_MACRO(module, MAP_PRIVATE); +#endif +#ifdef MAP_DENYWRITE + ADD_INT_MACRO(module, MAP_DENYWRITE); +#endif +#ifdef MAP_EXECUTABLE + ADD_INT_MACRO(module, MAP_EXECUTABLE); +#endif +#ifdef MAP_ANONYMOUS + if (PyModule_AddIntConstant(module, "MAP_ANON", MAP_ANONYMOUS) < 0 ) { + return -1; + } + ADD_INT_MACRO(module, MAP_ANONYMOUS); +#endif +#ifdef MAP_POPULATE + ADD_INT_MACRO(module, MAP_POPULATE); +#endif + if (PyModule_AddIntConstant(module, "PAGESIZE", (long)my_getpagesize()) < 0 ) { + return -1; + } + + if (PyModule_AddIntConstant(module, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()) < 0 ) { + return -1; + } + + ADD_INT_MACRO(module, ACCESS_DEFAULT); + ADD_INT_MACRO(module, ACCESS_READ); + ADD_INT_MACRO(module, ACCESS_WRITE); + ADD_INT_MACRO(module, ACCESS_COPY); + +#ifdef HAVE_MADVISE + // Conventional advice values +#ifdef MADV_NORMAL + ADD_INT_MACRO(module, MADV_NORMAL); +#endif +#ifdef MADV_RANDOM + ADD_INT_MACRO(module, MADV_RANDOM); +#endif +#ifdef MADV_SEQUENTIAL + ADD_INT_MACRO(module, MADV_SEQUENTIAL); +#endif +#ifdef MADV_WILLNEED + ADD_INT_MACRO(module, MADV_WILLNEED); +#endif +#ifdef MADV_DONTNEED + ADD_INT_MACRO(module, MADV_DONTNEED); +#endif + + // Linux-specific advice values +#ifdef MADV_REMOVE + ADD_INT_MACRO(module, MADV_REMOVE); +#endif +#ifdef MADV_DONTFORK + ADD_INT_MACRO(module, MADV_DONTFORK); +#endif +#ifdef MADV_DOFORK + ADD_INT_MACRO(module, MADV_DOFORK); +#endif +#ifdef MADV_HWPOISON + ADD_INT_MACRO(module, MADV_HWPOISON); +#endif +#ifdef MADV_MERGEABLE + ADD_INT_MACRO(module, MADV_MERGEABLE); +#endif +#ifdef MADV_UNMERGEABLE + ADD_INT_MACRO(module, MADV_UNMERGEABLE); +#endif +#ifdef MADV_SOFT_OFFLINE + ADD_INT_MACRO(module, MADV_SOFT_OFFLINE); +#endif +#ifdef MADV_HUGEPAGE + ADD_INT_MACRO(module, MADV_HUGEPAGE); +#endif +#ifdef MADV_NOHUGEPAGE + ADD_INT_MACRO(module, MADV_NOHUGEPAGE); +#endif +#ifdef MADV_DONTDUMP + ADD_INT_MACRO(module, MADV_DONTDUMP); +#endif +#ifdef MADV_DODUMP + ADD_INT_MACRO(module, MADV_DODUMP); +#endif +#ifdef MADV_FREE // (Also present on FreeBSD and macOS.) + ADD_INT_MACRO(module, MADV_FREE); +#endif + + // FreeBSD-specific +#ifdef MADV_NOSYNC + ADD_INT_MACRO(module, MADV_NOSYNC); +#endif +#ifdef MADV_AUTOSYNC + ADD_INT_MACRO(module, MADV_AUTOSYNC); +#endif +#ifdef MADV_NOCORE + ADD_INT_MACRO(module, MADV_NOCORE); +#endif +#ifdef MADV_CORE + ADD_INT_MACRO(module, MADV_CORE); +#endif +#ifdef MADV_PROTECT + ADD_INT_MACRO(module, MADV_PROTECT); +#endif +#endif // HAVE_MADVISE + return 0; } +static PyModuleDef_Slot mmap_slots[] = { + {Py_mod_exec, mmap_exec}, + {0, NULL} +}; static struct PyModuleDef mmapmodule = { PyModuleDef_HEAD_INIT, - "mmap", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL + .m_name = "mmap", + .m_size = 0, + .m_slots = mmap_slots, }; PyMODINIT_FUNC PyInit_mmap(void) { - PyObject *dict, *module; - - if (PyType_Ready(&mmap_object_type) < 0) - return NULL; - - module = PyModule_Create(&mmapmodule); - if (module == NULL) - return NULL; - dict = PyModule_GetDict(module); - if (!dict) - return NULL; - PyDict_SetItemString(dict, "error", PyExc_OSError); - PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); -#ifdef PROT_EXEC - setint(dict, "PROT_EXEC", PROT_EXEC); -#endif -#ifdef PROT_READ - setint(dict, "PROT_READ", PROT_READ); -#endif -#ifdef PROT_WRITE - setint(dict, "PROT_WRITE", PROT_WRITE); -#endif - -#ifdef MAP_SHARED - setint(dict, "MAP_SHARED", MAP_SHARED); -#endif -#ifdef MAP_PRIVATE - setint(dict, "MAP_PRIVATE", MAP_PRIVATE); -#endif -#ifdef MAP_DENYWRITE - setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); -#endif -#ifdef MAP_EXECUTABLE - setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); -#endif -#ifdef MAP_ANONYMOUS - setint(dict, "MAP_ANON", MAP_ANONYMOUS); - setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); -#endif -#ifdef MAP_POPULATE - setint(dict, "MAP_POPULATE", MAP_POPULATE); -#endif - - setint(dict, "PAGESIZE", (long)my_getpagesize()); - - setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); - - setint(dict, "ACCESS_DEFAULT", ACCESS_DEFAULT); - setint(dict, "ACCESS_READ", ACCESS_READ); - setint(dict, "ACCESS_WRITE", ACCESS_WRITE); - setint(dict, "ACCESS_COPY", ACCESS_COPY); - -#ifdef HAVE_MADVISE - // Conventional advice values -#ifdef MADV_NORMAL - setint(dict, "MADV_NORMAL", MADV_NORMAL); -#endif -#ifdef MADV_RANDOM - setint(dict, "MADV_RANDOM", MADV_RANDOM); -#endif -#ifdef MADV_SEQUENTIAL - setint(dict, "MADV_SEQUENTIAL", MADV_SEQUENTIAL); -#endif -#ifdef MADV_WILLNEED - setint(dict, "MADV_WILLNEED", MADV_WILLNEED); -#endif -#ifdef MADV_DONTNEED - setint(dict, "MADV_DONTNEED", MADV_DONTNEED); -#endif - - // Linux-specific advice values -#ifdef MADV_REMOVE - setint(dict, "MADV_REMOVE", MADV_REMOVE); -#endif -#ifdef MADV_DONTFORK - setint(dict, "MADV_DONTFORK", MADV_DONTFORK); -#endif -#ifdef MADV_DOFORK - setint(dict, "MADV_DOFORK", MADV_DOFORK); -#endif -#ifdef MADV_HWPOISON - setint(dict, "MADV_HWPOISON", MADV_HWPOISON); -#endif -#ifdef MADV_MERGEABLE - setint(dict, "MADV_MERGEABLE", MADV_MERGEABLE); -#endif -#ifdef MADV_UNMERGEABLE - setint(dict, "MADV_UNMERGEABLE", MADV_UNMERGEABLE); -#endif -#ifdef MADV_SOFT_OFFLINE - setint(dict, "MADV_SOFT_OFFLINE", MADV_SOFT_OFFLINE); -#endif -#ifdef MADV_HUGEPAGE - setint(dict, "MADV_HUGEPAGE", MADV_HUGEPAGE); -#endif -#ifdef MADV_NOHUGEPAGE - setint(dict, "MADV_NOHUGEPAGE", MADV_NOHUGEPAGE); -#endif -#ifdef MADV_DONTDUMP - setint(dict, "MADV_DONTDUMP", MADV_DONTDUMP); -#endif -#ifdef MADV_DODUMP - setint(dict, "MADV_DODUMP", MADV_DODUMP); -#endif -#ifdef MADV_FREE // (Also present on FreeBSD and macOS.) - setint(dict, "MADV_FREE", MADV_FREE); -#endif - - // FreeBSD-specific -#ifdef MADV_NOSYNC - setint(dict, "MADV_NOSYNC", MADV_NOSYNC); -#endif -#ifdef MADV_AUTOSYNC - setint(dict, "MADV_AUTOSYNC", MADV_AUTOSYNC); -#endif -#ifdef MADV_NOCORE - setint(dict, "MADV_NOCORE", MADV_NOCORE); -#endif -#ifdef MADV_CORE - setint(dict, "MADV_CORE", MADV_CORE); -#endif -#ifdef MADV_PROTECT - setint(dict, "MADV_PROTECT", MADV_PROTECT); -#endif -#endif // HAVE_MADVISE - - return module; + return PyModuleDef_Init(&mmapmodule); }