diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-08-06 17:08:01 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-08-06 17:08:01 (GMT) |
commit | ebfc6a8ebcef2b42beb6ef12e4946bb2f73f2723 (patch) | |
tree | 2a1eeb714ea15ff0ca0da9cada3c5aeb38a7e1cc | |
parent | cdfe7b0efbb358fdb3fff8f6d5a8d34d89b220e5 (diff) |
Secured the links between instructions.
-rw-r--r-- | src/arch/instruction.c | 123 | ||||
-rw-r--r-- | src/arch/instruction.h | 3 |
2 files changed, 126 insertions, 0 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 1bf3c9b..5ce0c12 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -208,6 +208,18 @@ static void g_arch_instruction_dispose(GArchInstruction *instr) g_arch_instruction_unlock_operands(instr); +#ifndef NDEBUG + g_arch_instruction_lock_src(instr); + assert(count_flat_array_items(instr->from) == 0); + g_arch_instruction_unlock_src(instr); +#endif + +#ifndef NDEBUG + g_arch_instruction_lock_dest(instr); + assert(count_flat_array_items(instr->to) == 0); + g_arch_instruction_unlock_dest(instr); +#endif + G_OBJECT_CLASS(g_arch_instruction_parent_class)->dispose(G_OBJECT(instr)); } @@ -791,11 +803,15 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des new_src.linked = instr; new_src.type = type; + ref_instr_link((&new_src)); + /* Côté point de départ */ new_dst.linked = dest; new_dst.type = type; + ref_instr_link((&new_dst)); + /* Ajout dans le respect d'une cohérence globale */ g_arch_instruction_lock_src(dest); @@ -898,6 +914,113 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d /****************************************************************************** * * +* Paramètres : instr = instruction dont les informations sont à traiter. * +* * +* Description : Supprime tous les liens établis avec d'autres instructions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_delete_all_links(GArchInstruction *instr) +{ + instr_link_t *link_src; /* Lien à supprimer #2 */ + GArchInstruction *other; /* Instruction de l'autre bout */ + size_t count; /* Quantié de liens présents */ + size_t i; /* Boucle de parcours */ + instr_link_t *link_dst; /* Lien à supprimer #1 */ + + /* Coté sources */ + + g_arch_instruction_lock_src(instr); + + while (count_flat_array_items(instr->from) > 0) + { + link_src = get_flat_array_item(instr->from, 0, sizeof(instr_link_t)); + + other = link_src->linked; + + g_arch_instruction_lock_dest(other); + + count = count_flat_array_items(other->to); + + for (i = 0; i < count; i++) + { + link_dst = get_flat_array_item(other->to, i, sizeof(instr_link_t)); + + if (link_dst->linked == instr && link_dst->type == link_src->type) + { + unref_instr_link(link_dst); + + rem_item_from_flat_array(&other->to, i, sizeof(instr_link_t)); + + break; + + } + + } + + assert(i < count); + + g_arch_instruction_unlock_dest(other); + + unref_instr_link(link_src); + + rem_item_from_flat_array(&instr->from, 0, sizeof(instr_link_t)); + + } + + g_arch_instruction_unlock_src(instr); + + /* Coté destinations */ + + g_arch_instruction_lock_dest(instr); + + while (count_flat_array_items(instr->to) > 0) + { + link_dst = get_flat_array_item(instr->to, 0, sizeof(instr_link_t)); + + other = link_dst->linked; + + g_arch_instruction_lock_src(other); + + count = count_flat_array_items(other->from); + + for (i = 0; i < count; i++) + { + link_src = get_flat_array_item(other->from, i, sizeof(instr_link_t)); + + if (link_src->linked == instr && link_src->type == link_dst->type) + { + unref_instr_link(link_src); + + rem_item_from_flat_array(&other->from, i, sizeof(instr_link_t)); + + break; + + } + + } + + assert(i < count); + + g_arch_instruction_unlock_src(other); + + unref_instr_link(link_dst); + + rem_item_from_flat_array(&instr->to, 0, sizeof(instr_link_t)); + + } + + g_arch_instruction_unlock_dest(instr); + +} + + +/****************************************************************************** +* * * Paramètres : instr = instruction dont les informations sont à consulter. * * * * Description : Fournit la quantité d'instructions pointant vers une autre. * diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 0c8510a..8289a43 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -227,6 +227,9 @@ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, Instru /* Change la nature d'un lien entre deux instructions. */ bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType); +/* Supprime tous les liens établis avec d'autres instructions. */ +void g_arch_instruction_delete_all_links(GArchInstruction *); + #define g_arch_instruction_lock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true) #define g_arch_instruction_unlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false) |