diff options
author | Christian Tismer <tismer@stackless.com> | 2020-08-13 16:10:10 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2020-08-14 10:03:33 +0200 |
commit | 58a0d36d9271e91bd21272a9fe3b736dd90db58d (patch) | |
tree | 594e7b328845048e60a03de07aad10ea13099d91 /sources/pyside2/libpyside | |
parent | 4457db11f873b29bd46c268126cbbdea6b397eee (diff) |
feature-select: delay the feature switching
Feature switching was written rather naively and happened after
almost every module change which can occour very often.
This patch is much more careful with switching and uses an ignore
code to prevent switching when PySide was not imported at all.
A potential regression when a switch is set before some PySide
module is being imported and PepType_SOTP is zero was also solved.
Task-number: PYSIDE-1019
Change-Id: I24dec7b3e4d0b577f77262392ded0b8a2006b3cc
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/pyside2/libpyside')
-rw-r--r-- | sources/pyside2/libpyside/feature_select.cpp | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/sources/pyside2/libpyside/feature_select.cpp b/sources/pyside2/libpyside/feature_select.cpp index c703d18c4..d3beeef7a 100644 --- a/sources/pyside2/libpyside/feature_select.cpp +++ b/sources/pyside2/libpyside/feature_select.cpp @@ -132,27 +132,33 @@ static FeatureProc *featurePointer = nullptr; static PyObject *cached_globals = nullptr; static PyObject *last_select_id = nullptr; -static PyObject *fast_id_array[256] = {}; +static PyObject *_fast_id_array[1 + 256] = {}; +// this will point to element 1 to allow indexing from -1 +static PyObject **fast_id_array; static inline PyObject *getFeatureSelectId() { - static PyObject *zero = fast_id_array[0]; + static PyObject *undef = fast_id_array[-1]; static PyObject *feature_dict = GetFeatureDict(); // these things are all borrowed PyObject *globals = PyEval_GetGlobals(); - if (globals == nullptr) - return zero; - if (globals == cached_globals) + if ( globals == nullptr + || globals == cached_globals) return last_select_id; PyObject *modname = PyDict_GetItem(globals, PyMagicName::name()); if (modname == nullptr) - return zero; + return last_select_id; + PyObject *select_id = PyDict_GetItem(feature_dict, modname); - if (select_id == nullptr || !PyInt_Check(select_id)) // int/long cheating - return zero; + if ( select_id == nullptr + || !PyInt_Check(select_id) // int/long cheating + || select_id == undef) + return last_select_id; + cached_globals = globals; last_select_id = select_id; + assert(PyInt_AsSsize_t(select_id) >= 0); return select_id; } @@ -378,6 +384,12 @@ static inline PyObject *SelectFeatureSet(PyTypeObject *type) } PyObject *select_id = getFeatureSelectId(); // borrowed PyObject *current_id = getCurrentSelectId(type); // borrowed + static PyObject *undef = fast_id_array[-1]; + + // PYSIDE-1019: During import PepType_SOTP is still zero. + if (current_id == undef) + current_id = select_id = fast_id_array[0]; + if (select_id != current_id) { PyObject *mro = type->tp_mro; Py_ssize_t idx, n = PyTuple_GET_SIZE(mro); @@ -424,7 +436,7 @@ static FeatureProc featureProcArray[] = { void finalize() { - for (int idx = 0; idx < 256; ++idx) + for (int idx = -1; idx < 256; ++idx) Py_DECREF(fast_id_array[idx]); } @@ -433,8 +445,10 @@ void init() // This function can be called multiple times. static bool is_initialized = false; if (!is_initialized) { - for (int idx = 0; idx < 256; ++idx) + fast_id_array = &_fast_id_array[1]; + for (int idx = -1; idx < 256; ++idx) fast_id_array[idx] = PyInt_FromLong(idx); + last_select_id = fast_id_array[0]; featurePointer = featureProcArray; initSelectableFeature(SelectFeatureSet); registerCleanupFunction(finalize); |