summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2022-05-27 16:31:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2022-05-27 16:31:43 (GMT)
commit89f802045b71299ba70a8df17ca09d5fcc37cf99 (patch)
tree39151ac4736adc02c64a0ee0009bd8c7364958ed /plugins
parentd23c70ce953d27a5c2cbe0ec1516d8749d0d2616 (diff)
Avoid calls to Python _PyDict_NewKeysForClass() internal function.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/pychrysalide/helpers.c129
1 files changed, 45 insertions, 84 deletions
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index b04c801..8e7c10c 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -717,7 +717,7 @@ PyObject *not_yet_implemented_getter(PyObject *self, void *closure)
/******************************************************************************
* *
-* Paramètres : spec = définition à mettre en place dynamiquement. *
+* Paramètres : otype = définition à mettre en place dynamiquement. *
* *
* Description : Définit dans le tas de Python un nouveau type. *
* *
@@ -727,102 +727,63 @@ PyObject *not_yet_implemented_getter(PyObject *self, void *closure)
* *
******************************************************************************/
-PyTypeObject *define_python_dynamic_type(const PyTypeObject *spec)
+PyTypeObject *define_python_dynamic_type(const PyTypeObject *otype)
{
PyTypeObject *result; /* Définition créée à renvoyer */
- PyTypeObject *type; /* Type de tous les types */
- size_t size; /* Taille de la définition */
- char *s; /* Marqueur de début de chaîne */
- PyHeapTypeObject *hobj; /* Version réelle du type créé */
+ PyType_Slot slots[10]; /* Emplacements pour infos */
+ PyType_Spec spec; /* Définition du type */
+ PyType_Slot *iter; /* Boucle de parcours */
+ PyObject *bases; /* Bases de construction */
- /**
- * Le cahier des charges est ici d'éviter les erreurs suivantes :
- *
- * TypeError: type 'XXX' is not dynamically allocated but its base type 'YYY' is dynamically allocated
- * Fatal Python error: unexpected exception during garbage collection
- *
- * L'allocation dynamique est marquée par le fanion Py_TPFLAGS_HEAPTYPE.
- *
- * Une des rares fonctions qui appliquent ce fanion est PyType_FromSpecWithBases(),
- * mais elle appelle ensuite PyType_Ready(), ce qui est incompatible avec des modifications
- * utltérieures avant un appel à pygobject_register_class().
- *
- * Le code suivant s'inspire fortement des méthodes originales de Python,
- * dont les mécanismes employés par PyType_GenericAlloc().
- */
-
- type = &PyType_Type;
- size = _PyObject_SIZE(type);
-
- if (PyType_IS_GC(type))
- result = (PyTypeObject *)_PyObject_GC_Malloc(size);
- else
- result = (PyTypeObject *)PyObject_MALLOC(size);
-
- if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
- Py_INCREF(type);
-
- /* Définitions sommaires */
-
- memset(result, 0, sizeof(PyHeapTypeObject));
-
- memcpy(result, spec, sizeof(PyTypeObject));
-
- result->tp_flags |= Py_TPFLAGS_HEAPTYPE;
-
- /* Définitions des noms */
-
- /**
- * Pour un type dynamique, les désignations ne s'appuient pas sur la partie réservée
- * au type, mais sur les données suivantes (cf. type_name() et type_qualname()).
- *
- * Les deux fonctions désignées sont par ailleurs facilement accessibles :
- *
- * #0 0x0000555555689bf0 in type_qualname (...) at Objects/typeobject.c:393
- * #1 0x000055555568b3b4 in type_repr (...) at Objects/typeobject.c:855
- * #2 0x0000555555693574 in object_str (...) at Objects/typeobject.c:3511
- * #3 0x0000555555670d02 in PyObject_Str (...) at Objects/object.c:535
- * ...
- *
- * On s'inspire donc du contenu de PyType_FromSpecWithBases() pour éviter tout
- * plantage du fait de données non initialisées.
- */
+ bases = PyTuple_Pack(1, &PyType_Type);
- hobj = (PyHeapTypeObject *)result;
+ spec.name = otype->tp_name;
+ spec.basicsize = otype->tp_basicsize;
+ spec.flags = otype->tp_flags;
+ spec.slots = slots;
- s = strrchr(spec->tp_name, '.');
-
- if (s == NULL)
- s = (char *)spec->tp_name;
- else
- s++;
+ iter = &slots[0];
- hobj->ht_name = PyUnicode_FromString(s);
- assert(hobj->ht_name != NULL);
-
- hobj->ht_qualname = hobj->ht_name;
- Py_INCREF(hobj->ht_qualname);
+ if (otype->tp_doc != NULL)
+ {
+ iter->slot = Py_tp_doc;
+ iter->pfunc = (void *)otype->tp_doc;
+ iter++;
+ }
- result->tp_as_async = &hobj->as_async;
- result->tp_as_number = &hobj->as_number;
- result->tp_as_sequence = &hobj->as_sequence;
- result->tp_as_mapping = &hobj->as_mapping;
- result->tp_as_buffer = &hobj->as_buffer;
+ if (otype->tp_methods != NULL)
+ {
+ iter->slot = Py_tp_methods;
+ iter->pfunc = otype->tp_methods;
+ iter++;
+ }
- hobj->ht_cached_keys = _PyDict_NewKeysForClass();
+ if (otype->tp_getset != NULL)
+ {
+ iter->slot = Py_tp_getset;
+ iter->pfunc = otype->tp_getset;
+ iter++;
+ }
+ if (otype->tp_init != NULL)
+ {
+ iter->slot = Py_tp_init;
+ iter->pfunc = otype->tp_init;
+ iter++;
+ }
+ if (otype->tp_new != NULL)
+ {
+ iter->slot = Py_tp_new;
+ iter->pfunc = otype->tp_new;
+ iter++;
+ }
+ iter->slot = 0;
-#if 0
- if (type->tp_itemsize == 0)
- (void)PyObject_INIT(result, type);
- else
- (void) PyObject_INIT_VAR((PyVarObject *)result, type, 0);
+ result = (PyTypeObject *)PyType_FromSpecWithBases(&spec, bases);
- if (PyType_IS_GC(type))
- _PyObject_GC_TRACK(result);
-#endif
+ Py_DECREF(bases);
return result;