Skip to content

Commit fe9f446

Browse files
author
Erlend Egeberg Aasland
authored
bpo-41798: Allocate _decimal extension module C API on the heap (GH-24117)
1 parent 315fc52 commit fe9f446

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

Include/pydecimal.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ typedef struct {
6666
/* Capsule API */
6767
/****************************************************************************/
6868

69+
#define PyDec_CAPSULE_NAME "_decimal._API"
70+
6971
/* Simple API */
7072
#define PyDec_TypeCheck_INDEX 0
7173
#define PyDec_TypeCheck_RETURN int
@@ -164,7 +166,7 @@ static void **_decimal_api;
164166
static int
165167
import_decimal(void)
166168
{
167-
_decimal_api = (void **)PyCapsule_Import("_decimal._API", 0);
169+
_decimal_api = (void **)PyCapsule_Import(PyDec_CAPSULE_NAME, 0);
168170
if (_decimal_api == NULL) {
169171
return -1;
170172
}

Modules/_decimal/_decimal.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5574,8 +5574,6 @@ static PyTypeObject PyDecContext_Type =
55745574
/* C-API */
55755575
/****************************************************************************/
55765576

5577-
static void *_decimal_api[CPYTHON_DECIMAL_MAX_API];
5578-
55795577
/* Simple API */
55805578
static int
55815579
PyDec_TypeCheck(const PyObject *v)
@@ -5699,9 +5697,22 @@ PyDec_GetConst(const PyObject *v)
56995697
return MPD(v);
57005698
}
57015699

5700+
static void
5701+
destroy_api(PyObject *capsule)
5702+
{
5703+
void *capi = PyCapsule_GetPointer(capsule, PyDec_CAPSULE_NAME);
5704+
PyMem_Free(capi);
5705+
}
5706+
57025707
static PyObject *
57035708
init_api(void)
57045709
{
5710+
void **_decimal_api = PyMem_Calloc(CPYTHON_DECIMAL_MAX_API, sizeof(void *));
5711+
if (_decimal_api == NULL) {
5712+
PyErr_NoMemory();
5713+
return NULL;
5714+
}
5715+
57055716
/* Simple API */
57065717
_decimal_api[PyDec_TypeCheck_INDEX] = (void *)PyDec_TypeCheck;
57075718
_decimal_api[PyDec_IsSpecial_INDEX] = (void *)PyDec_IsSpecial;
@@ -5716,7 +5727,11 @@ init_api(void)
57165727
_decimal_api[PyDec_Get_INDEX] = (void *)PyDec_Get;
57175728
_decimal_api[PyDec_GetConst_INDEX] = (void *)PyDec_GetConst;
57185729

5719-
return PyCapsule_New(_decimal_api, "_decimal._API", NULL);
5730+
PyObject *capsule = PyCapsule_New(_decimal_api, PyDec_CAPSULE_NAME, destroy_api);
5731+
if (!capsule) {
5732+
PyMem_Free(_decimal_api);
5733+
}
5734+
return capsule;
57205735
}
57215736

57225737

@@ -6080,8 +6095,7 @@ PyInit__decimal(void)
60806095
CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
60816096

60826097
/* Add capsule API */
6083-
Py_INCREF(capsule);
6084-
if (PyModule_AddObject(m, "_API", capsule) < 0) {
6098+
if (PyModule_AddObjectRef(m, "_API", capsule) < 0) {
60856099
goto error;
60866100
}
60876101

@@ -6107,6 +6121,7 @@ PyInit__decimal(void)
61076121
Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
61086122
Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
61096123
Py_CLEAR(m); /* GCOV_NOT_REACHED */
6124+
Py_CLEAR(capsule); /* GCOV_NOT_REACHED */
61106125

61116126
return NULL; /* GCOV_NOT_REACHED */
61126127
}

0 commit comments

Comments
 (0)