diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-01-06 11:47:28 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-06 11:47:28 (GMT) |
commit | fe9f446afe46bd716592eda9fa2af8d9f46bbce4 (patch) | |
tree | 60d215c0e59eeb8c54062e4486dc496fbabfc416 | |
parent | 315fc52db17b19fe30aa9193f26adf69e18d8844 (diff) | |
download | cpython-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.h | 4 | ||||
-rw-r--r-- | Modules/_decimal/_decimal.c | 25 |
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 */ } |