aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/libpyside
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2020-08-13 16:10:10 +0200
committerChristian Tismer <tismer@stackless.com>2020-08-14 10:03:33 +0200
commit58a0d36d9271e91bd21272a9fe3b736dd90db58d (patch)
tree594e7b328845048e60a03de07aad10ea13099d91 /sources/pyside2/libpyside
parent4457db11f873b29bd46c268126cbbdea6b397eee (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.cpp34
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);