Skip to content

Commit a21405a

Browse files
Immortalize all methods in builtins module
1 parent e7295a8 commit a21405a

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

Include/internal/pycore_modsupport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern PyObject ** _Py_VaBuildStack(
3939
Py_ssize_t *p_nargs);
4040

4141
extern PyObject* _PyModule_CreateInitialized(PyModuleDef*, int apiver);
42+
extern PyObject *_PyModule_CreateInitializedImmortalMethods(PyModuleDef* module, int module_api_version);
4243

4344
// Export for '_curses' shared extension
4445
PyAPI_FUNC(int) _PyArg_ParseStack(
@@ -91,6 +92,8 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords(
9192
_PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \
9293
(minpos), (maxpos), (minkw), (varpos), (buf)))
9394

95+
int _PyModule_AddFunctionsImmortal(PyObject *m, PyMethodDef *functions);
96+
9497
#ifdef __cplusplus
9598
}
9699
#endif

Objects/moduleobject.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ check_api_version(const char *name, int module_api_version)
171171
}
172172

173173
static int
174-
_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
174+
_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions, int immortalize_methods)
175175
{
176176
PyObject *func;
177177
PyMethodDef *fdef;
@@ -188,7 +188,12 @@ _add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
188188
if (func == NULL) {
189189
return -1;
190190
}
191-
_PyObject_SetDeferredRefcount(func);
191+
if (immortalize_methods) {
192+
_Py_SetImmortal(func);
193+
}
194+
else {
195+
_PyObject_SetDeferredRefcount(func);
196+
}
192197
if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) {
193198
Py_DECREF(func);
194199
return -1;
@@ -210,8 +215,10 @@ PyModule_Create2(PyModuleDef* module, int module_api_version)
210215
return _PyModule_CreateInitialized(module, module_api_version);
211216
}
212217

213-
PyObject *
214-
_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
218+
typedef int (*module_addfunctions_ptr)(PyObject *, PyMethodDef *);
219+
220+
static PyObject *
221+
module_createinitialized_impl(PyModuleDef* module, int module_api_version, module_addfunctions_ptr module_addfunctions)
215222
{
216223
const char* name;
217224
PyModuleObject *m;
@@ -245,7 +252,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
245252
}
246253

247254
if (module->m_methods != NULL) {
248-
if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
255+
if (module_addfunctions((PyObject *) m, module->m_methods) != 0) {
249256
Py_DECREF(m);
250257
return NULL;
251258
}
@@ -263,6 +270,18 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
263270
return (PyObject*)m;
264271
}
265272

273+
PyObject *
274+
_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
275+
{
276+
return module_createinitialized_impl(module, module_api_version, PyModule_AddFunctions);
277+
}
278+
279+
PyObject *
280+
_PyModule_CreateInitializedImmortalMethods(PyModuleDef* module, int module_api_version)
281+
{
282+
return module_createinitialized_impl(module, module_api_version, _PyModule_AddFunctionsImmortal);
283+
}
284+
266285
PyObject *
267286
PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version)
268287
{
@@ -422,7 +441,7 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio
422441
}
423442

424443
if (def->m_methods != NULL) {
425-
ret = _add_methods_to_object(m, nameobj, def->m_methods);
444+
ret = _add_methods_to_object(m, nameobj, def->m_methods, 0);
426445
if (ret != 0) {
427446
goto error;
428447
}
@@ -535,7 +554,21 @@ PyModule_AddFunctions(PyObject *m, PyMethodDef *functions)
535554
return -1;
536555
}
537556

538-
res = _add_methods_to_object(m, name, functions);
557+
res = _add_methods_to_object(m, name, functions, 0);
558+
Py_DECREF(name);
559+
return res;
560+
}
561+
562+
int
563+
_PyModule_AddFunctionsImmortal(PyObject *m, PyMethodDef *functions)
564+
{
565+
int res;
566+
PyObject *name = PyModule_GetNameObject(m);
567+
if (name == NULL) {
568+
return -1;
569+
}
570+
571+
res = _add_methods_to_object(m, name, functions, 1);
539572
Py_DECREF(name);
540573
return res;
541574
}

Python/bltinmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3414,7 +3414,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)
34143414

34153415
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
34163416

3417-
mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION);
3417+
mod = _PyModule_CreateInitializedImmortalMethods(&builtinsmodule, PYTHON_API_VERSION);
34183418
if (mod == NULL)
34193419
return NULL;
34203420
#ifdef Py_GIL_DISABLED

0 commit comments

Comments
 (0)