summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-01-06 11:47:28 (GMT)
committerGitHub <noreply@github.com>2021-01-06 11:47:28 (GMT)
commitfe9f446afe46bd716592eda9fa2af8d9f46bbce4 (patch)
tree60d215c0e59eeb8c54062e4486dc496fbabfc416
parent315fc52db17b19fe30aa9193f26adf69e18d8844 (diff)
downloadcpython-fe9f446afe46bd716592eda9fa2af8d9f46bbce4.zip
cpython-fe9f446afe46bd716592eda9fa2af8d9f46bbce4.tar.gz
cpython-fe9f446afe46bd716592eda9fa2af8d9f46bbce4.tar.bz2
bpo-41798: Allocate _decimal extension module C API on the heap (GH-24117)
-rw-r--r--Include/pydecimal.h4
-rw-r--r--Modules/_decimal/_decimal.c25
2 files changed, 23 insertions, 6 deletions
diff --git a/Include/pydecimal.h b/Include/pydecimal.h
index 9b6440e..f82e41f 100644
--- a/Include/pydecimal.h
+++ b/Include/pydecimal.h
@@ -66,6 +66,8 @@ typedef struct {
/* Capsule API */
/****************************************************************************/
+#define PyDec_CAPSULE_NAME "_decimal._API"
+
/* Simple API */
#define PyDec_TypeCheck_INDEX 0
#define PyDec_TypeCheck_RETURN int
@@ -164,7 +166,7 @@ static void **_decimal_api;
static int
import_decimal(void)
{
- _decimal_api = (void **)PyCapsule_Import("_decimal._API", 0);
+ _decimal_api = (void **)PyCapsule_Import(PyDec_CAPSULE_NAME, 0);
if (_decimal_api == NULL) {
return -1;
}
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 9c85d76..664d45a 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -5574,8 +5574,6 @@ static PyTypeObject PyDecContext_Type =
/* C-API */
/****************************************************************************/
-static void *_decimal_api[CPYTHON_DECIMAL_MAX_API];
-
/* Simple API */
static int
PyDec_TypeCheck(const PyObject *v)
@@ -5699,9 +5697,22 @@ PyDec_GetConst(const PyObject *v)
return MPD(v);
}
+static void
+destroy_api(PyObject *capsule)
+{
+ void *capi = PyCapsule_GetPointer(capsule, PyDec_CAPSULE_NAME);
+ PyMem_Free(capi);
+}
+
static PyObject *
init_api(void)
{
+ void **_decimal_api = PyMem_Calloc(CPYTHON_DECIMAL_MAX_API, sizeof(void *));
+ if (_decimal_api == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
/* Simple API */
_decimal_api[PyDec_TypeCheck_INDEX] = (void *)PyDec_TypeCheck;
_decimal_api[PyDec_IsSpecial_INDEX] = (void *)PyDec_IsSpecial;
@@ -5716,7 +5727,11 @@ init_api(void)
_decimal_api[PyDec_Get_INDEX] = (void *)PyDec_Get;
_decimal_api[PyDec_GetConst_INDEX] = (void *)PyDec_GetConst;
- return PyCapsule_New(_decimal_api, "_decimal._API", NULL);
+ PyObject *capsule = PyCapsule_New(_decimal_api, PyDec_CAPSULE_NAME, destroy_api);
+ if (!capsule) {
+ PyMem_Free(_decimal_api);
+ }
+ return capsule;
}
@@ -6080,8 +6095,7 @@ PyInit__decimal(void)
CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
/* Add capsule API */
- Py_INCREF(capsule);
- if (PyModule_AddObject(m, "_API", capsule) < 0) {
+ if (PyModule_AddObjectRef(m, "_API", capsule) < 0) {
goto error;
}
@@ -6107,6 +6121,7 @@ error:
Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
Py_CLEAR(m); /* GCOV_NOT_REACHED */
+ Py_CLEAR(capsule); /* GCOV_NOT_REACHED */
return NULL; /* GCOV_NOT_REACHED */
}