From 32bef30025f5e3f513c2b4936c0573cc3b629961 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 8 Feb 2019 00:42:02 +0100 Subject: Rewritten some Python instance allocation functions. --- plugins/pychrysalide/arch/instriter.c | 43 +------------- plugins/pychrysalide/arch/vmpa.c | 104 ++++++++++++++++++++-------------- plugins/pychrysalide/common/bits.c | 81 ++++++++++++++++++++------ plugins/pychrysalide/format/symiter.c | 43 +------------- 4 files changed, 125 insertions(+), 146 deletions(-) diff --git a/plugins/pychrysalide/arch/instriter.c b/plugins/pychrysalide/arch/instriter.c index 9b149fd..bb1e1a3 100644 --- a/plugins/pychrysalide/arch/instriter.c +++ b/plugins/pychrysalide/arch/instriter.c @@ -57,9 +57,6 @@ static PyObject *py_instr_iterator_next(PyInstrIterator *); /* Initialise un nouvel itérateur. */ static int py_instr_iterator_init(PyInstrIterator *, PyObject *, PyObject *); -/* Construit un nouvel itérateur. */ -static PyObject *py_instr_iterator_new(PyTypeObject *, PyObject *, PyObject *); - /****************************************************************************** @@ -172,44 +169,6 @@ static int py_instr_iterator_init(PyInstrIterator *self, PyObject *args, PyObjec /****************************************************************************** * * -* Paramètres : type = type d'objet à mettre en place. * -* args = arguments passés pour l'appel. * -* kwds = mots clefs éventuellement fournis en complément. * -* * -* Description : Construit un nouvel itérateur. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_instr_iterator_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyInstrIterator *result; /* Nouvelle instance à renvoyer*/ - int ret; /* Bilan de l'initialisation */ - - result = (PyInstrIterator *)type->tp_alloc(type, 0); - - if (result != NULL) - { - ret = py_instr_iterator_init(result, args, kwds); - - if (ret != 0) - { - Py_DECREF(result); - result = NULL; - } - - } - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -239,7 +198,7 @@ PyTypeObject *get_python_instr_iterator_type(void) .tp_iternext = (iternextfunc)py_instr_iterator_next, .tp_init = (initproc)py_instr_iterator_init, - .tp_new = py_instr_iterator_new, + .tp_new = PyType_GenericNew, }; diff --git a/plugins/pychrysalide/arch/vmpa.c b/plugins/pychrysalide/arch/vmpa.c index 0474fe0..b042a9f 100644 --- a/plugins/pychrysalide/arch/vmpa.c +++ b/plugins/pychrysalide/arch/vmpa.c @@ -70,8 +70,8 @@ static PyObject *py_vmpa_get_value(PyObject *, void *); /* Définit une partie du contenu de la position représentée. */ static int py_vmpa_set_value(PyObject *, PyObject *, void *); -/* Crée un nouvel objet Python de type 'vmpa2t'. */ -static PyObject *py_vmpa_new(PyTypeObject *, PyObject *, PyObject *); +/* Initialise un objet Python de type 'vmpa2t'. */ +static int py_vmpa_init(py_vmpa_t *, PyObject *, PyObject *); /* Effectue une conversion d'un objet Python en type 'vmpa_t'. */ static bool convert_pyobj_to_vmpa(PyObject *, vmpa2t *); @@ -130,9 +130,8 @@ static PyObject *py_mrange_get_end_addr(PyObject *, void *); - -/* Crée un nouvel objet Python de type 'mrange'. */ -static PyObject *py_mrange_new(PyTypeObject *, PyObject *, PyObject *); +/* Initialise un objet Python de type 'mrange_t'. */ +static int py_mrange_init(py_mrange_t *, PyObject *, PyObject *); @@ -380,40 +379,42 @@ static int py_vmpa_set_value(PyObject *self, PyObject *value, void *closure) /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * +* Paramètres : self = instance d'objet à initialiser. * +* args = arguments passés pour l'appel. * +* kwds = mots clefs éventuellement fournis en complément. * * * -* Description : Crée un nouvel objet Python de type 'vmpa2t'. * +* Description : Initialise un objet Python de type 'vmpa2t'. * * * -* Retour : Instance Python mise en place. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_vmpa_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_vmpa_init(py_vmpa_t *self, PyObject *args, PyObject *kwds) { - py_vmpa_t *result; /* Instance à retourner */ + int result; /* Bilan à retourner */ unsigned long long phy; /* Position physique */ unsigned long long virt; /* Adresse en mémoire virtuelle*/ int ret; /* Bilan de lecture des args. */ + result = -1; + phy = VMPA_NO_PHYSICAL; virt = VMPA_NO_VIRTUAL; ret = PyArg_ParseTuple(args, "|KK", &phy, &virt); - if (!ret) return NULL; - - result = (py_vmpa_t *)type->tp_alloc(type, 0); + if (!ret) goto exit; - init_vmpa(&result->addr, phy, virt); + init_vmpa(&self->addr, phy, virt); - return (PyObject *)result; + result = 0; -} + exit: + return result; +} @@ -637,7 +638,9 @@ PyTypeObject *get_python_vmpa_type(void) .tp_richcompare = py_vmpa_richcompare, .tp_getset = py_vmpa_getseters, - .tp_new = py_vmpa_new + + .tp_init = (initproc)py_vmpa_init, + .tp_new = PyType_GenericNew, }; @@ -723,16 +726,19 @@ vmpa2t *get_internal_vmpa(PyObject *obj) PyObject *build_from_internal_vmpa(const vmpa2t *addr) { - py_vmpa_t *result; /* Instance à retourner */ + PyObject *result; /* Instance à retourner */ PyTypeObject *type; /* Type à instancier */ + PyObject *args; /* Liste des arguments d'appel */ type = get_python_vmpa_type(); - result = (py_vmpa_t *)type->tp_alloc(type, 0); + args = Py_BuildValue("KK", get_phy_addr(addr), get_virt_addr(addr)); - copy_vmpa(&result->addr, addr); + result = PyObject_CallObject((PyObject *)type, args); - return (PyObject *)result; + Py_DECREF(args); + + return result; } @@ -1122,45 +1128,46 @@ static PyObject *py_mrange_get_end_addr(PyObject *self, void *closure) /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * +* Paramètres : self = instance d'objet à initialiser. * +* args = arguments passés pour l'appel. * +* kwds = mots clefs éventuellement fournis en complément. * * * -* Description : Crée un nouvel objet Python de type 'mrange'. * +* Description : Initialise un objet Python de type 'mrange_t'. * * * -* Retour : Instance Python mise en place. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_mrange_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_mrange_init(py_mrange_t *self, PyObject *args, PyObject *kwds) { - py_mrange_t *result; /* Instance à retourner */ + int result; /* Bilan à retourner */ PyObject *py_vmpa; /* Localisation version Python */ unsigned long long length; /* Taille physique */ int ret; /* Bilan de lecture des args. */ vmpa2t *addr; /* Localisation version C */ + result = -1; + ret = PyArg_ParseTuple(args, "OK", &py_vmpa, &length); - if (!ret) return NULL; + if (!ret) goto exit; ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type()); - if (!ret) return NULL; + if (!ret) goto exit; addr = get_internal_vmpa(py_vmpa); - if (addr == NULL) return NULL; + if (addr == NULL) goto exit; - result = (py_mrange_t *)type->tp_alloc(type, 0); + init_mrange(&self->range, addr, length); - init_mrange(&result->range, addr, length); - - return (PyObject *)result; - -} + result = 0; + exit: + return result; +} @@ -1231,7 +1238,9 @@ PyTypeObject *get_python_mrange_type(void) .tp_methods = py_mrange_methods, .tp_getset = py_mrange_getseters, - .tp_new = py_mrange_new + + .tp_init = (initproc)py_mrange_init, + .tp_new = PyType_GenericNew, }; @@ -1314,15 +1323,22 @@ mrange_t *get_internal_mrange(PyObject *obj) PyObject *build_from_internal_mrange(const mrange_t *range) { - py_mrange_t *result; /* Instance à retourner */ + PyObject *result; /* Instance à retourner */ PyTypeObject *type; /* Type à instancier */ + PyObject *addr_obj; /* Objet pour l'adresse de base*/ + PyObject *args; /* Liste des arguments d'appel */ type = get_python_mrange_type(); - result = (py_mrange_t *)type->tp_alloc(type, 0); + addr_obj = build_from_internal_vmpa(get_mrange_addr(range)); - copy_mrange(&result->range, range); + args = Py_BuildValue("OK", addr_obj, get_mrange_length(range)); - return (PyObject *)result; + result = PyObject_CallObject((PyObject *)type, args); + + Py_DECREF(args); + Py_DECREF(addr_obj); + + return result; } diff --git a/plugins/pychrysalide/common/bits.c b/plugins/pychrysalide/common/bits.c index 7a6454d..c3bacd4 100644 --- a/plugins/pychrysalide/common/bits.c +++ b/plugins/pychrysalide/common/bits.c @@ -41,8 +41,11 @@ typedef struct _py_bitfield_t -/* Crée un nouvel objet Python de type 'bitfield_t'. */ -static PyObject *py_bitfield_new(PyTypeObject *, PyObject *, PyObject *); +/* Libère de la mémoire un objet Python de type 'bitfield_t'. */ +static void py_bitfield_dealloc(py_bitfield_t *); + +/* Initialise un objet Python de type 'bitfield_t'. */ +static int py_bitfield_init(py_bitfield_t *, PyObject *, PyObject *); /* Crée une copie d'un champ de bits classique. */ static PyObject *py_bitfield_dup(PyObject *, PyObject *); @@ -93,33 +96,58 @@ static PyObject *py_bitfield_popcount(PyObject *, void *); /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * +* Paramètres : self = champ de bits à supprimer. * +* * +* Description : Libère de la mémoire un objet Python de type 'bitfield_t'. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_bitfield_dealloc(py_bitfield_t *self) +{ + delete_bit_field(self->native); + + Py_TYPE(self)->tp_free((PyObject *)self); + +} + + +/****************************************************************************** +* * +* Paramètres : self = instance d'objet à initialiser. * +* args = arguments passés pour l'appel. * +* kwds = mots clefs éventuellement fournis en complément. * * * -* Description : Crée un nouvel objet Python de type 'bitfield_t'. * +* Description : Initialise un objet Python de type 'bitfield_t'. * * * -* Retour : Instance Python mise en place. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_bitfield_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_bitfield_init(py_bitfield_t *self, PyObject *args, PyObject *kwds) { - py_bitfield_t *result; /* Instance à retourner */ + int result; /* Bilan à retourner */ unsigned long length; /* Taille du champ à créer */ int state; /* Initialisation par défaut */ int ret; /* Bilan de lecture des args. */ + result = -1; + ret = PyArg_ParseTuple(args, "kp", &length, &state); - if (!ret) return NULL; + if (ret == 0) goto exit; + + self->native = create_bit_field(length, state); - result = (py_bitfield_t *)type->tp_alloc(type, 0); + result = 0; - result->native = create_bit_field(length, state); + exit: - return (PyObject *)result; + return result; } @@ -726,6 +754,8 @@ PyTypeObject *get_python_bitfield_type(void) .tp_name = "pychrysalide.common.bitfield", .tp_basicsize = sizeof(py_bitfield_t), + .tp_dealloc = (destructor)py_bitfield_dealloc, + .tp_as_number = &py_bitfield_nb_proto, .tp_as_sequence = &py_bitfield_sequence_proto, @@ -737,7 +767,9 @@ PyTypeObject *get_python_bitfield_type(void) .tp_methods = py_bitfield_methods, .tp_getset = py_bitfield_getseters, - .tp_new = py_bitfield_new + + .tp_init = (initproc)py_bitfield_init, + .tp_new = PyType_GenericNew, }; @@ -796,15 +828,28 @@ bool ensure_python_bitfield_is_registered(void) PyObject *build_from_internal_bitfield(const bitfield_t *field) { - py_bitfield_t *result; /* Instance à retourner */ + PyObject *result; /* Instance à retourner */ PyTypeObject *type; /* Type à instancier */ + PyObject *args; /* Liste des arguments d'appel */ + py_bitfield_t *bf_obj; /* Objet précis instancié */ type = get_python_bitfield_type(); - result = (py_bitfield_t *)type->tp_alloc(type, 0); + /** + * Le format "p" n'existe pas pour Py_BuildValue(). + */ + args = Py_BuildValue("kk", 0, 0); + + result = PyObject_CallObject((PyObject *)type, args); + + Py_DECREF(args); - result->native = dup_bit_field(field); + bf_obj = (py_bitfield_t *)result; - return (PyObject *)result; + delete_bit_field(bf_obj->native); + + bf_obj->native = dup_bit_field(field); + + return result; } diff --git a/plugins/pychrysalide/format/symiter.c b/plugins/pychrysalide/format/symiter.c index 03a0ec8..8deabe9 100644 --- a/plugins/pychrysalide/format/symiter.c +++ b/plugins/pychrysalide/format/symiter.c @@ -57,9 +57,6 @@ static PyObject *py_sym_iterator_next(PySymIterator *); /* Initialise un nouvel itérateur. */ static int py_sym_iterator_init(PySymIterator *, PyObject *, PyObject *); -/* Construit un nouvel itérateur. */ -static PyObject *py_sym_iterator_new(PyTypeObject *, PyObject *, PyObject *); - /****************************************************************************** @@ -172,44 +169,6 @@ static int py_sym_iterator_init(PySymIterator *self, PyObject *args, PyObject *k /****************************************************************************** * * -* Paramètres : type = type d'objet à mettre en place. * -* args = arguments passés pour l'appel. * -* kwds = mots clefs éventuellement fournis en complément. * -* * -* Description : Construit un nouvel itérateur. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_sym_iterator_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PySymIterator *result; /* Nouvelle instance à renvoyer*/ - int ret; /* Bilan de l'initialisation */ - - result = (PySymIterator *)type->tp_alloc(type, 0); - - if (result != NULL) - { - ret = py_sym_iterator_init(result, args, kwds); - - if (ret != 0) - { - Py_DECREF(result); - result = NULL; - } - - } - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -239,7 +198,7 @@ PyTypeObject *get_python_sym_iterator_type(void) .tp_iternext = (iternextfunc)py_sym_iterator_next, .tp_init = (initproc)py_sym_iterator_init, - .tp_new = py_sym_iterator_new, + .tp_new = PyType_GenericNew, }; -- cgit v0.11.2-87-g4458