diff options
Diffstat (limited to 'src/arch')
| -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)  | 
