From 5b53b8712726429784cd8854b78dc846dada3da2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard 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