diff options
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r-- | src/arch/instruction.c | 85 |
1 files changed, 75 insertions, 10 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 14e78dc..a2ba138 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -30,6 +30,7 @@ #include "instruction-int.h" +#include "sharing/container-int.h" #include "../glibext/linegen-int.h" @@ -40,8 +41,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_arch_instruction_init(GArchInstruction *); +/* Procède à l'initialisation de l'interface de partage. */ +static void g_arch_instruction_share_interface_init(GShareContainerInterface *); + /* Procède à l'initialisation de l'interface de génération. */ -static void g_arch_instruction_interface_init(GLineGeneratorInterface *); +static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *); /* Supprime toutes les références externes. */ static void g_arch_instruction_dispose(GArchInstruction *); @@ -76,7 +80,8 @@ static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, /* Indique le type défini pour une instruction d'architecture. */ G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init)); + G_IMPLEMENT_INTERFACE(G_TYPE_SHARE_CONTAINER, g_arch_instruction_share_interface_init) + G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_interface_init)); /****************************************************************************** @@ -134,6 +139,25 @@ static void g_arch_instruction_init(GArchInstruction *instr) * * * Paramètres : iface = interface GLib à initialiser. * * * +* Description : Procède à l'initialisation de l'interface de partage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_share_interface_init(GShareContainerInterface *iface) +{ + iface->replace = (replace_shared_fc)g_arch_instruction_replace_operand; + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * * Description : Procède à l'initialisation de l'interface de génération. * * * * Retour : - * @@ -142,7 +166,7 @@ static void g_arch_instruction_init(GArchInstruction *instr) * * ******************************************************************************/ -static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface) +static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *iface) { iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines; iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr; @@ -475,8 +499,8 @@ void g_arch_instruction_unlock_operands(GArchInstruction *instr) /****************************************************************************** * * -* Paramètres : instr = instance à mettre à jour. * -* opererand = instruction à venir associer. * +* Paramètres : instr = instance à mettre à jour. * +* operand = instruction à venir associer. * * * * Description : Attache un opérande supplémentaire à une instruction. * * * @@ -552,23 +576,55 @@ GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, siz /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * -* new = nouvelle opérande à attacher. * +* old = ancien opérande à remplacer. * +* new = nouvel opérande à intégrer. * +* * +* Description : Remplace un opérande d'une instruction par un autre. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new) +{ + bool result; /* Bilan à retourner */ + + g_arch_instruction_lock_operands(instr); + + result = _g_arch_instruction_replace_operand(instr, old, new); + + g_arch_instruction_unlock_operands(instr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance à mettre à jour. * * old = ancienne opérande à détacher. * +* new = nouvelle opérande à attacher. * * * * Description : Remplace un opérande d'une instruction par un autre. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, GArchOperand *old) +bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new) { + bool result; /* Bilan à retourner */ size_t count; /* Nombre d'opérandes en place */ size_t i; /* Boucle de parcours */ GArchOperand *op; /* Opérande à manipuler */ + result = false; + count = _g_arch_instruction_count_operands(instr); for (i = 0; i < count; i++) @@ -576,13 +632,22 @@ void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand * op = _g_arch_instruction_get_operand(instr, i); if (op == old) + { + result = true; break; + } } - rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *)); + if (result) + { + rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *)); + + g_object_unref(G_OBJECT(old)); - g_object_unref(G_OBJECT(old)); + } + + return result; } |