From 5b53b8712726429784cd8854b78dc846dada3da2 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 21 May 2023 23:21:05 +0200
Subject: Delete an extra level of types for the Python bindings instructions.

---
 plugins/pychrysalide/arch/instruction.c | 281 ++++++--------------------------
 src/arch/instruction.h                  |  12 +-
 2 files changed, 52 insertions(+), 241 deletions(-)

diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index 3606cfe..5acb3bd 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -45,52 +45,7 @@
 
 
 
-/* -------------------- INTERFACE INTERNE POUR EXTENSIONS PYTHON -------------------- */
-
-
-/* Définition générique d'une instruction d'architecture (instance) */
-typedef struct _GPyArchInstruction
-{
-    GArchInstruction parent;                /* A laisser en premier        */
-
-    char *cached_keyword;                   /* Conservation de constante   */
-
-} GPyArchInstruction;
-
-
-/* Définition générique d'une instruction d'architecture (classe) */
-typedef struct _GPyArchInstructionClass
-{
-    GArchInstructionClass parent;           /* A laisser en premier        */
-
-} GPyArchInstructionClass;
-
-
-#define G_TYPE_PYARCH_INSTRUCTION            g_pyarch_instruction_get_type()
-#define G_PYARCH_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PYARCH_INSTRUCTION, GPyArchInstruction))
-#define G_IS_PYTHON_INSTRUCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PYARCH_INSTRUCTION))
-#define G_PYARCH_INSTRUCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PYARCH_INSTRUCTION, GPyArchInstructionClass))
-#define G_IS_PYTHON_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PYARCH_INSTRUCTION))
-#define G_PYARCH_INSTRUCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PYARCH_INSTRUCTION, GPyArchInstructionClass))
-
-
-/* Indique le type défini pour une instruction d'architecture en Python. */
-GType g_pyarch_instruction_get_type(void);
-
-/* Initialise la classe générique des instructions en Python. */
-static void g_pyarch_instruction_class_init(GPyArchInstructionClass *);
-
-/* Initialise une instance d'opérande d'architecture. */
-static void g_pyarch_instruction_init(GPyArchInstruction *);
-
-/* Supprime toutes les références externes. */
-static void g_pyarch_instruction_dispose(GPyArchInstruction *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_pyarch_instruction_finalize(GPyArchInstruction *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static const char *g_pyarch_instruction_get_keyword(GPyArchInstruction *);
+static G_DEFINE_QUARK(cached_keyword, get_cached_keyword);
 
 
 
@@ -101,11 +56,16 @@ static const char *g_pyarch_instruction_get_keyword(GPyArchInstruction *);
 static PyObject *py_arch_instruction_new(PyTypeObject *, PyObject *, PyObject *);
 
 /* Initialise la classe générique des instructions. */
-static void py_arch_instruction_init_gclass(GPyArchInstructionClass *, gpointer);
+static void py_arch_instruction_init_gclass(GArchInstructionClass *, gpointer);
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(arch_instruction, G_TYPE_ARCH_INSTRUCTION, py_arch_instruction_init_gclass);
 
 /* Initialise une instance sur la base du dérivé de GObject. */
 static int py_arch_instruction_init(PyObject *, PyObject *, PyObject *);
 
+/* Fournit le nom humain de l'instruction manipulée. */
+static const char *py_arch_instruction_get_class_keyword(GArchInstruction *);
+
 
 
 /* --------------------------- MANIPULATION DES OPERANDES --------------------------- */
@@ -160,19 +120,16 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
 
 
 /* ---------------------------------------------------------------------------------- */
-/*                      INTERFACE INTERNE POUR EXTENSIONS PYTHON                      */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
 /* ---------------------------------------------------------------------------------- */
 
 
-/* Indique le type défini pour une instruction d'architecture en Python. */
-G_DEFINE_TYPE(GPyArchInstruction, g_pyarch_instruction, G_TYPE_ARCH_INSTRUCTION);
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
+*  Paramètres  : class  = classe à initialiser.                               *
+*                unused = données non utilisées ici.                          *
 *                                                                             *
-*  Description : Initialise la classe générique des instructions en Python.   *
+*  Description : Initialise la classe générique des instructions.             *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -180,78 +137,62 @@ G_DEFINE_TYPE(GPyArchInstruction, g_pyarch_instruction, G_TYPE_ARCH_INSTRUCTION)
 *                                                                             *
 ******************************************************************************/
 
-static void g_pyarch_instruction_class_init(GPyArchInstructionClass *klass)
+static void py_arch_instruction_init_gclass(GArchInstructionClass *class, gpointer unused)
 {
-    GObjectClass *object;                   /* Autre version de la classe  */
     GArchInstructionClass *instr;           /* Encore une autre vision...  */
 
-    object = G_OBJECT_CLASS(klass);
+    instr = G_ARCH_INSTRUCTION_CLASS(class);
 
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_pyarch_instruction_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_pyarch_instruction_finalize;
-
-    instr = G_ARCH_INSTRUCTION_CLASS(klass);
-
-    instr->get_keyword = (get_instruction_keyword_fc)g_pyarch_instruction_get_keyword;
+    instr->get_keyword = (get_instruction_keyword_fc)py_arch_instruction_get_class_keyword;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : instr = instance à initialiser.                              *
+*  Paramètres  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
 *                                                                             *
-*  Description : Initialise une instance d'instruction d'architecture.        *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : 0.                                                           *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_pyarch_instruction_init(GPyArchInstruction *instr)
+static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
+    unsigned short int uid;                 /* Indentifiant unique de type */
+    const char *keyword;                    /* Désignation d'instruction   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GArchInstruction *instr;                /* Instruction à manipuler     */
+    GQuark cache_key;                       /* Emplacement local           */
 
-}
+    static char *kwlist[] = { "uid", "keyword", NULL };
 
+    /* Récupération des paramètres */
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr = instance d'objet GLib à traiter.                     *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+    ret = PyArg_ParseTupleAndKeywords(args, kwds, "Hs", kwlist, &uid, &keyword);
+    if (!ret) return -1;
 
-static void g_pyarch_instruction_dispose(GPyArchInstruction *instr)
-{
-    G_OBJECT_CLASS(g_pyarch_instruction_parent_class)->dispose(G_OBJECT(instr));
+    /* Initialisation d'un objet GLib */
 
-}
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
 
+    /* Eléments de base */
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr = instance d'objet GLib à traiter.                     *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+    instr = G_ARCH_INSTRUCTION(pygobject_get(self));
 
-static void g_pyarch_instruction_finalize(GPyArchInstruction *instr)
-{
-    if (instr->cached_keyword)
-        free(instr->cached_keyword);
+    cache_key = get_cached_keyword_quark();
 
-    G_OBJECT_CLASS(g_pyarch_instruction_parent_class)->finalize(G_OBJECT(instr));
+    g_object_set_qdata_full(G_OBJECT(instr), cache_key, strdup(keyword), g_free);
+
+    g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(instr), uid);
+
+    return 0;
 
 }
 
@@ -268,151 +209,21 @@ static void g_pyarch_instruction_finalize(GPyArchInstruction *instr)
 *                                                                             *
 ******************************************************************************/
 
-static const char *g_pyarch_instruction_get_keyword(GPyArchInstruction *instr)
+static const char *py_arch_instruction_get_class_keyword(GArchInstruction *instr)
 {
     const char *result;                     /* Désignation à retourner     */
+    GQuark cache_key;                       /* Emplacement local           */
 
-    result = instr->cached_keyword;
+    cache_key = get_cached_keyword_quark();
 
-    return result;
-
-}
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : type = type du nouvel objet à mettre en place.               *
-*                args = éventuelle liste d'arguments.                         *
-*                kwds = éventuel dictionnaire de valeurs mises à disposition. *
-*                                                                             *
-*  Description : Accompagne la création d'une instance dérivée en Python.     *
-*                                                                             *
-*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_arch_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
-    PyObject *result;                       /* Objet à retourner           */
-    PyTypeObject *base;                     /* Type de base à dériver      */
-    bool first_time;                        /* Evite les multiples passages*/
-    GType gtype;                            /* Nouveau type de processeur  */
-    bool status;                            /* Bilan d'un enregistrement   */
-
-    /* Validations diverses */
-
-    base = get_python_arch_instruction_type();
-
-    if (type == base)
-    {
-        result = NULL;
-        PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
-        goto exit;
-    }
-
-    /* Mise en place d'un type dédié */
-
-    first_time = (g_type_from_name(type->tp_name) == 0);
-
-    gtype = build_dynamic_type(G_TYPE_PYARCH_INSTRUCTION, type->tp_name,
-                               (GClassInitFunc)py_arch_instruction_init_gclass, NULL, NULL);
-
-    if (first_time)
-    {
-        status = register_class_for_dynamic_pygobject(gtype, type, base);
-
-        if (!status)
-        {
-            result = NULL;
-            goto exit;
-        }
-
-    }
-
-    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
-
-    result = PyType_GenericNew(type, args, kwds);
-
- exit:
+    result = g_object_get_qdata(G_OBJECT(instr), cache_key);
+    assert(result != NULL);
 
     return result;
 
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : class  = classe à initialiser.                               *
-*                unused = données non utilisées ici.                          *
-*                                                                             *
-*  Description : Initialise la classe générique des instructions.             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void py_arch_instruction_init_gclass(GPyArchInstructionClass *class, gpointer unused)
-{
-    /// ....
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = objet à initialiser (théoriquement).                  *
-*                args = arguments fournis à l'appel.                          *
-*                kwds = arguments de type key=val fournis.                    *
-*                                                                             *
-*  Description : Initialise une instance sur la base du dérivé de GObject.    *
-*                                                                             *
-*  Retour      : 0.                                                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    unsigned short int uid;                 /* Indentifiant unique de type */
-    const char *keyword;                    /* Désignation d'instruction   */
-    int ret;                                /* Bilan de lecture des args.  */
-    GPyArchInstruction *instr;              /* Instruction à manipuler     */
-
-    static char *kwlist[] = { "uid", "keyword", NULL };
-
-    /* Récupération des paramètres */
-
-    ret = PyArg_ParseTupleAndKeywords(args, kwds, "Hs", kwlist, &uid, &keyword);
-    if (!ret) return -1;
-
-    /* Initialisation d'un objet GLib */
-
-    ret = forward_pygobjet_init(self);
-    if (ret == -1) return -1;
-
-    /* Eléments de base */
-
-    instr = G_PYARCH_INSTRUCTION(pygobject_get(self));
-
-    instr->cached_keyword = strdup(keyword);
-
-    g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(instr), uid);
-
-    return 0;
-
-}
-
-
 
 /* ---------------------------------------------------------------------------------- */
 /*                             MANIPULATION DES OPERANDES                             */
@@ -1085,7 +896,7 @@ bool ensure_python_arch_instruction_is_registered(void)
         if (!ensure_python_line_generator_is_registered())
             return false;
 
-        if (!_register_class_for_pygobject(dict, G_TYPE_PYARCH_INSTRUCTION, type,
+        if (!_register_class_for_pygobject(dict, G_TYPE_ARCH_INSTRUCTION, type,
                                            &PyGObject_Type, get_python_line_generator_type(), NULL))
             return false;
 
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 26eadc9..3c9c149 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -38,12 +38,12 @@
 
 
 
-#define G_TYPE_ARCH_INSTRUCTION               g_arch_instruction_get_type()
-#define G_ARCH_INSTRUCTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction))
-#define G_IS_ARCH_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type()))
-#define G_ARCH_INSTRUCTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
-#define G_IS_ARCH_INSTRUCTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION))
-#define G_ARCH_INSTRUCTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
+#define G_TYPE_ARCH_INSTRUCTION            g_arch_instruction_get_type()
+#define G_ARCH_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction))
+#define G_IS_ARCH_INSTRUCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type()))
+#define G_ARCH_INSTRUCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
+#define G_IS_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION))
+#define G_ARCH_INSTRUCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
 
 
 /* Définition générique d'une instruction d'architecture (instance) */
-- 
cgit v0.11.2-87-g4458