Skip to content

Commit a1620dd

Browse files
gh-106078: Prepare to isolate decimal module (#106880)
* move signal_map to global_state * move cond_map to global_state
1 parent eeff8e7 commit a1620dd

File tree

2 files changed

+55
-23
lines changed

2 files changed

+55
-23
lines changed

Modules/_decimal/_decimal.c

+53-21
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#endif
4747

4848
struct PyDecContextObject;
49+
struct DecCondMap;
4950

5051
typedef struct {
5152
PyTypeObject *PyDecContextManager_Type;
@@ -82,6 +83,9 @@ typedef struct {
8283

8384
PyObject *SignalTuple;
8485

86+
struct DecCondMap *signal_map;
87+
struct DecCondMap *cond_map;
88+
8589
/* External C-API functions */
8690
binaryfunc _py_long_multiply;
8791
binaryfunc _py_long_floor_divide;
@@ -181,7 +185,7 @@ incr_false(void)
181185
#define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1)
182186
#define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED)
183187

184-
typedef struct {
188+
typedef struct DecCondMap {
185189
const char *name; /* condition or signal name */
186190
const char *fqname; /* fully qualified name */
187191
uint32_t flag; /* libmpdec flag */
@@ -193,7 +197,7 @@ typedef struct {
193197
#define INEXACT 6
194198
#define ROUNDED 7
195199
#define SIGNAL_MAP_LEN 9
196-
static DecCondMap signal_map[] = {
200+
static DecCondMap signal_map_template[] = {
197201
{"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
198202
{"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL},
199203
{"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL},
@@ -207,7 +211,7 @@ static DecCondMap signal_map[] = {
207211
};
208212

209213
/* Exceptions that inherit from InvalidOperation */
210-
static DecCondMap cond_map[] = {
214+
static DecCondMap cond_map_template[] = {
211215
{"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL},
212216
{"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL},
213217
{"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL},
@@ -219,6 +223,21 @@ static DecCondMap cond_map[] = {
219223
{NULL}
220224
};
221225

226+
/* Return a duplicate of DecCondMap template */
227+
static inline DecCondMap *
228+
dec_cond_map_init(DecCondMap *template, Py_ssize_t size)
229+
{
230+
DecCondMap *cm;
231+
cm = PyMem_Malloc(size);
232+
if (cm == NULL) {
233+
PyErr_NoMemory();
234+
return NULL;
235+
}
236+
237+
memcpy(cm, template, size);
238+
return cm;
239+
}
240+
222241
static const char *dec_signal_string[MPD_NUM_FLAGS] = {
223242
"Clamped",
224243
"InvalidOperation",
@@ -312,8 +331,9 @@ static PyObject *
312331
flags_as_exception(uint32_t flags)
313332
{
314333
DecCondMap *cm;
334+
decimal_state *state = GLOBAL_STATE();
315335

316-
for (cm = signal_map; cm->name != NULL; cm++) {
336+
for (cm = state->signal_map; cm->name != NULL; cm++) {
317337
if (flags&cm->flag) {
318338
return cm->ex;
319339
}
@@ -326,8 +346,9 @@ Py_LOCAL_INLINE(uint32_t)
326346
exception_as_flag(PyObject *ex)
327347
{
328348
DecCondMap *cm;
349+
decimal_state *state = GLOBAL_STATE();
329350

330-
for (cm = signal_map; cm->name != NULL; cm++) {
351+
for (cm = state->signal_map; cm->name != NULL; cm++) {
331352
if (cm->ex == ex) {
332353
return cm->flag;
333354
}
@@ -342,20 +363,21 @@ flags_as_list(uint32_t flags)
342363
{
343364
PyObject *list;
344365
DecCondMap *cm;
366+
decimal_state *state = GLOBAL_STATE();
345367

346368
list = PyList_New(0);
347369
if (list == NULL) {
348370
return NULL;
349371
}
350372

351-
for (cm = cond_map; cm->name != NULL; cm++) {
373+
for (cm = state->cond_map; cm->name != NULL; cm++) {
352374
if (flags&cm->flag) {
353375
if (PyList_Append(list, cm->ex) < 0) {
354376
goto error;
355377
}
356378
}
357379
}
358-
for (cm = signal_map+1; cm->name != NULL; cm++) {
380+
for (cm = state->signal_map+1; cm->name != NULL; cm++) {
359381
if (flags&cm->flag) {
360382
if (PyList_Append(list, cm->ex) < 0) {
361383
goto error;
@@ -375,13 +397,14 @@ signals_as_list(uint32_t flags)
375397
{
376398
PyObject *list;
377399
DecCondMap *cm;
400+
decimal_state *state = GLOBAL_STATE();
378401

379402
list = PyList_New(0);
380403
if (list == NULL) {
381404
return NULL;
382405
}
383406

384-
for (cm = signal_map; cm->name != NULL; cm++) {
407+
for (cm = state->signal_map; cm->name != NULL; cm++) {
385408
if (flags&cm->flag) {
386409
if (PyList_Append(list, cm->ex) < 0) {
387410
Py_DECREF(list);
@@ -421,13 +444,14 @@ flags_as_dict(uint32_t flags)
421444
{
422445
DecCondMap *cm;
423446
PyObject *dict;
447+
decimal_state *state = GLOBAL_STATE();
424448

425449
dict = PyDict_New();
426450
if (dict == NULL) {
427451
return NULL;
428452
}
429453

430-
for (cm = signal_map; cm->name != NULL; cm++) {
454+
for (cm = state->signal_map; cm->name != NULL; cm++) {
431455
PyObject *b = flags&cm->flag ? Py_True : Py_False;
432456
if (PyDict_SetItem(dict, cm->ex, b) < 0) {
433457
Py_DECREF(dict);
@@ -445,6 +469,7 @@ dict_as_flags(PyObject *val)
445469
DecCondMap *cm;
446470
uint32_t flags = 0;
447471
int x;
472+
decimal_state *state = GLOBAL_STATE();
448473

449474
if (!PyDict_Check(val)) {
450475
PyErr_SetString(PyExc_TypeError,
@@ -458,7 +483,7 @@ dict_as_flags(PyObject *val)
458483
return DEC_INVALID_SIGNALS;
459484
}
460485

461-
for (cm = signal_map; cm->name != NULL; cm++) {
486+
for (cm = state->signal_map; cm->name != NULL; cm++) {
462487
b = PyDict_GetItemWithError(val, cm->ex);
463488
if (b == NULL) {
464489
if (PyErr_Occurred()) {
@@ -652,7 +677,8 @@ signaldict_repr(PyObject *self)
652677

653678
assert(SIGNAL_MAP_LEN == 9);
654679

655-
for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
680+
decimal_state *state = GLOBAL_STATE();
681+
for (cm=state->signal_map, i=0; cm->name != NULL; cm++, i++) {
656682
n[i] = cm->fqname;
657683
b[i] = SdFlags(self)&cm->flag ? "True" : "False";
658684
}
@@ -5922,10 +5948,12 @@ PyInit__decimal(void)
59225948
ASSIGN_PTR(state->SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
59235949

59245950
/* Add exceptions that correspond to IEEE signals */
5951+
ASSIGN_PTR(state->signal_map, dec_cond_map_init(signal_map_template,
5952+
sizeof(signal_map_template)));
59255953
for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) {
59265954
PyObject *base;
59275955

5928-
cm = signal_map + i;
5956+
cm = state->signal_map + i;
59295957

59305958
switch (cm->flag) {
59315959
case MPD_Float_operation:
@@ -5936,13 +5964,13 @@ PyInit__decimal(void)
59365964
PyExc_ZeroDivisionError);
59375965
break;
59385966
case MPD_Overflow:
5939-
base = PyTuple_Pack(2, signal_map[INEXACT].ex,
5940-
signal_map[ROUNDED].ex);
5967+
base = PyTuple_Pack(2, state->signal_map[INEXACT].ex,
5968+
state->signal_map[ROUNDED].ex);
59415969
break;
59425970
case MPD_Underflow:
5943-
base = PyTuple_Pack(3, signal_map[INEXACT].ex,
5944-
signal_map[ROUNDED].ex,
5945-
signal_map[SUBNORMAL].ex);
5971+
base = PyTuple_Pack(3, state->signal_map[INEXACT].ex,
5972+
state->signal_map[ROUNDED].ex,
5973+
state->signal_map[SUBNORMAL].ex);
59465974
break;
59475975
default:
59485976
base = PyTuple_Pack(1, state->DecimalException);
@@ -5968,16 +5996,18 @@ PyInit__decimal(void)
59685996
* several conditions, including InvalidOperation! Naming the
59695997
* signal IEEEInvalidOperation would prevent the confusion.
59705998
*/
5971-
cond_map[0].ex = signal_map[0].ex;
5999+
ASSIGN_PTR(state->cond_map, dec_cond_map_init(cond_map_template,
6000+
sizeof(cond_map_template)));
6001+
state->cond_map[0].ex = state->signal_map[0].ex;
59726002

59736003
/* Add remaining exceptions, inherit from InvalidOperation */
5974-
for (cm = cond_map+1; cm->name != NULL; cm++) {
6004+
for (cm = state->cond_map+1; cm->name != NULL; cm++) {
59756005
PyObject *base;
59766006
if (cm->flag == MPD_Division_undefined) {
5977-
base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError);
6007+
base = PyTuple_Pack(2, state->signal_map[0].ex, PyExc_ZeroDivisionError);
59786008
}
59796009
else {
5980-
base = PyTuple_Pack(1, signal_map[0].ex);
6010+
base = PyTuple_Pack(1, state->signal_map[0].ex);
59816011
}
59826012
if (base == NULL) {
59836013
goto error; /* GCOV_NOT_REACHED */
@@ -6057,6 +6087,8 @@ PyInit__decimal(void)
60576087
Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */
60586088
Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
60596089
Py_CLEAR(state->SignalTuple); /* GCOV_NOT_REACHED */
6090+
PyMem_Free(state->signal_map); /* GCOV_NOT_REACHED */
6091+
PyMem_Free(state->cond_map); /* GCOV_NOT_REACHED */
60606092
Py_CLEAR(state->DecimalTuple); /* GCOV_NOT_REACHED */
60616093
Py_CLEAR(state->default_context_template); /* GCOV_NOT_REACHED */
60626094
#ifndef WITH_DECIMAL_CONTEXTVAR

Tools/c-analyzer/cpython/ignored.tsv

+2-2
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,13 @@ Modules/_datetimemodule.c - max_fold_seconds -
205205
Modules/_datetimemodule.c datetime_isoformat specs -
206206
Modules/_datetimemodule.c parse_hh_mm_ss_ff correction -
207207
Modules/_datetimemodule.c time_isoformat specs -
208-
Modules/_decimal/_decimal.c - cond_map -
208+
Modules/_decimal/_decimal.c - cond_map_template -
209209
Modules/_decimal/_decimal.c - dec_signal_string -
210210
Modules/_decimal/_decimal.c - dflt_ctx -
211211
Modules/_decimal/_decimal.c - int_constants -
212212
Modules/_decimal/_decimal.c - invalid_rounding_err -
213213
Modules/_decimal/_decimal.c - invalid_signals_err -
214-
Modules/_decimal/_decimal.c - signal_map -
214+
Modules/_decimal/_decimal.c - signal_map_template -
215215
Modules/_decimal/_decimal.c - ssize_constants -
216216
Modules/_elementtree.c - ExpatMemoryHandler -
217217
Modules/_hashopenssl.c - py_hashes -

0 commit comments

Comments
 (0)