aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2020-08-01 12:14:33 +0200
committerChristian Tismer <tismer@stackless.com>2020-08-04 16:04:40 +0200
commit96345e5684d825ac75bc2d63f0491f5d19f4d5c6 (patch)
tree8e44005b94d3d64897f39a08a5b9fe81786e09d5
parentf2c973af4bd7cc1d87ec8ccfecadb7a475b723da (diff)
feature_select: Apply tiny name switching optimization and cleanup
After the big optimization of selectable features, the cached select Id-s can also be used to simplify the case selection. Also, the MSVC glitch with signed bitfields is circumvented by unsigned bitfields. Further a merge error was reverted which killed signature: Clean up and improve readability 3d4d91334 Christian Tismer <tismer@stackless.com> 10. Jul 2020 at 11:06 Change-Id: I783dc6d73b88016e70c58daeb207f1537fb38f72 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/shiboken2/libshiboken/basewrapper_p.h12
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.cpp10
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp49
3 files changed, 42 insertions, 29 deletions
diff --git a/sources/shiboken2/libshiboken/basewrapper_p.h b/sources/shiboken2/libshiboken/basewrapper_p.h
index 685b4fbe5..482a3ea2a 100644
--- a/sources/shiboken2/libshiboken/basewrapper_p.h
+++ b/sources/shiboken2/libshiboken/basewrapper_p.h
@@ -130,16 +130,16 @@ struct SbkObjectTypePrivate
TypeDiscoveryFuncV2 type_discovery;
/// Pointer to a function responsible for deletion of the C++ instance calling the proper destructor.
ObjectDestructor cpp_dtor;
+ /// PYSIDE-1019: Caching the current select Id
+ unsigned int pyside_reserved_bits : 8; // MSVC has bug with the sign bit!
/// True if this type holds two or more C++ instances, e.g.: a Python class which inherits from two C++ classes.
- int is_multicpp : 1;
+ unsigned int is_multicpp : 1;
/// True if this type was defined by the user.
- int is_user_type : 1;
+ unsigned int is_user_type : 1;
/// Tells is the type is a value type or an object-type, see BEHAVIOUR_ *constants.
// TODO-CONVERTERS: to be deprecated/removed
- int type_behaviour : 2;
- int delete_in_main_thread : 1;
- /// PYSIDE-1019: Caching the current select Id
- int pyside_reserved_bits : 9; // MSVC needs the sign bit! Buglet?
+ unsigned int type_behaviour : 2;
+ unsigned int delete_in_main_thread : 1;
/// C++ name
char *original_name;
/// Type user data
diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp
index b35a02ef4..4f8c6068a 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken2/libshiboken/bindingmanager.cpp
@@ -274,16 +274,10 @@ SbkObject *BindingManager::retrieveWrapper(const void *cptr)
return iter->second;
}
-static bool mangleNameFlag(PyTypeObject *type)
+static inline bool mangleNameFlag(PyTypeObject *type)
{
// PYSIDE-1019: See if a dict is set with a snake_case bit.
- static PyTypeObject *old_dict_type = Py_TYPE(PyType_Type.tp_dict);
- auto dict = type->tp_dict;
- if (Py_TYPE(dict) == old_dict_type)
- return false;
- Shiboken::AutoDecRef select_id(PyObject_GetAttr(dict, Shiboken::PyName::select_id()));
- auto id = PyInt_AsSsize_t(select_id);
- return (id & 1) != 0;
+ return (SbkObjectType_GetReserved(type) & 1) != 0;
}
PyObject *BindingManager::getOverride(const void *cptr, PyObject *methodNameCache[2], const char *methodName)
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 4614a131e..e4dc27ea7 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -653,17 +653,22 @@ _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
}
}
}
- // staticmethod has just a __doc__ in the class
- assert(strcmp(type->tp_name, "staticmethod") == 0);
+ PyMemberDef *md = type->tp_members;
+ if (md != nullptr)
+ for (; md->name != nullptr; md++)
+ if (strcmp(md->name, name) == 0)
+ return 1;
+ // staticmethod has just a `__doc__` in the class
+ assert(strcmp(type->tp_name, "staticmethod") == 0 && strcmp(name, "__doc__") == 0);
return 0;
}
static int
-add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
+add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr)
{
/*
- * This function is used to assign a new __signature__ attribute,
- * and also to override a __doc__ attribute.
+ * This function is used to assign a new `__signature__` attribute,
+ * and also to override a `__doc__` or `__name__` attribute.
*/
assert(PyType_Check(type));
PyType_Ready(type);
@@ -671,9 +676,11 @@ add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
for (; gsp->name != nullptr; gsp++) {
PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
if (have_descr != nullptr) {
- assert(strcmp(gsp->name, "__doc__") == 0);
Py_INCREF(have_descr);
- *old_descr = have_descr;
+ if (strcmp(gsp->name, "__doc__") == 0)
+ *doc_descr = have_descr;
+ else
+ assert(false);
if (!_fixup_getset(type, gsp->name, gsp))
continue;
}
@@ -824,7 +831,7 @@ static PyGetSetDef new_PyWrapperDescr_getsets[] = {
//
// Additionally to the interface via __signature__, we also provide
// a general function, which allows for different signature layouts.
-// The "modifier" argument is a string that is passed in from loader.py .
+// The "modifier" argument is a string that is passed in from 'loader.py'.
// Configuration what the modifiers mean is completely in Python.
//
@@ -909,13 +916,25 @@ PySide_PatchTypes(void)
reinterpret_cast<PyObject *>(&PyString_Type), "split"));
Shiboken::AutoDecRef wrap_descr(PyObject_GetAttrString(
reinterpret_cast<PyObject *>(Py_TYPE(Py_True)), "__add__"));
+ // abbreviations for readability
+ auto md_gs = new_PyMethodDescr_getsets;
+ auto md_doc = &old_md_doc_descr;
+ auto cf_gs = new_PyCFunction_getsets;
+ auto cf_doc = &old_cf_doc_descr;
+ auto sm_gs = new_PyStaticMethod_getsets;
+ auto sm_doc = &old_sm_doc_descr;
+ auto tp_gs = new_PyType_getsets;
+ auto tp_doc = &old_tp_doc_descr;
+ auto wd_gs = new_PyWrapperDescr_getsets;
+ auto wd_doc = &old_wd_doc_descr;
+
if (meth_descr.isNull() || wrap_descr.isNull()
|| PyType_Ready(Py_TYPE(meth_descr)) < 0
- || add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets, &old_md_doc_descr) < 0
- || add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets, &old_cf_doc_descr) < 0
- || add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets, &old_sm_doc_descr) < 0
- || add_more_getsets(&PyType_Type, new_PyType_getsets, &old_tp_doc_descr) < 0
- || add_more_getsets(Py_TYPE(wrap_descr), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
+ || add_more_getsets(PepMethodDescr_TypePtr, md_gs, md_doc) < 0
+ || add_more_getsets(&PyCFunction_Type, cf_gs, cf_doc) < 0
+ || add_more_getsets(PepStaticMethod_TypePtr, sm_gs, sm_doc) < 0
+ || add_more_getsets(&PyType_Type, tp_gs, tp_doc) < 0
+ || add_more_getsets(Py_TYPE(wrap_descr), wd_gs, wd_doc) < 0
)
return -1;
#ifndef _WIN32
@@ -1214,8 +1233,8 @@ FinishSignatureInitialization(PyObject *module, const char *signatures[])
* Still, it is not possible to call init phase 2 from here,
* because the import is still running. Do it from Python!
*/
- PySide_PatchTypes();
- if (PySide_FinishSignatures(module, signatures) < 0) {
+ if ( PySide_PatchTypes() < 0
+ || PySide_FinishSignatures(module, signatures) < 0) {
PyErr_Print();
PyErr_SetNone(PyExc_ImportError);
}