diff options
Diffstat (limited to 'src/analysis/block.c')
-rw-r--r-- | src/analysis/block.c | 320 |
1 files changed, 35 insertions, 285 deletions
diff --git a/src/analysis/block.c b/src/analysis/block.c index a23634c..7003ccd 100644 --- a/src/analysis/block.c +++ b/src/analysis/block.c @@ -50,9 +50,6 @@ static void g_code_block_finalize(GCodeBlock *); /* Indique l'indice d'intégration du bloc dans une liste. */ static void g_code_block_set_index(GCodeBlock *, size_t); -/* Etablit les liens entre un bloc de code et ses voisins. */ -static void g_code_block_resolve_links(GCodeBlock *, const GBlockList *); - /* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */ @@ -137,12 +134,11 @@ static void g_code_block_class_init(GCodeBlockClass *class) static void g_code_block_init(GCodeBlock *block) { + block->list = NULL; + block->index = (size_t)-1; block->rank = (size_t)-1; - block->from = NULL; - block->to = NULL; - block->view = NULL; } @@ -162,17 +158,7 @@ static void g_code_block_init(GCodeBlock *block) static void g_code_block_dispose(GCodeBlock *block) { -#ifndef NDEBUG - g_code_block_lock_src(block); - assert(count_flat_array_items(block->from) == 0); - g_code_block_unlock_src(block); -#endif - -#ifndef NDEBUG - g_code_block_lock_dest(block); - assert(count_flat_array_items(block->to) == 0); - g_code_block_unlock_dest(block); -#endif + g_clear_object(&block->list); g_clear_object(&block->view); @@ -297,30 +283,6 @@ bool g_code_block_is_starting_with(const GCodeBlock *block, const vmpa2t *addr) /****************************************************************************** * * -* Paramètres : block = bloc de code à mettre à jour. * -* list = ensemble des blocs de code à disposition. * -* * -* Description : Etablit les liens entre un bloc de code et ses voisins. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_code_block_resolve_links(GCodeBlock *block, const GBlockList *list) -{ - GCodeBlockClass *class; /* Classe des blocs de code */ - - class = G_CODE_BLOCK_GET_CLASS(block); - - class->link(block, list); - -} - - -/****************************************************************************** -* * * Paramètres : block = bloc de code à consulter. * * * * Description : Fournit le rang du bloc de code dans le flot d'exécution. * @@ -405,205 +367,36 @@ GBufferView *g_code_block_get_view(GCodeBlock *block, segcnt_list *highlighted) /****************************************************************************** * * -* Paramètres : block = bloc de code à mettre à jour. * -* src = sélection de l'extrémité à traiter. * -* lock = indique le sens du verrouillage à mener. * -* * -* Description : Met à disposition un encadrement des accès aux liens. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_code_block_lock_unlock_links(GCodeBlock *block, bool src, bool lock) -{ - flat_array_t **array; /* Choix du tableau ciblé */ - - array = (src ? &block->from : &block->to); - - if (lock) - lock_flat_array(array); - else - unlock_flat_array(array); - -} - - -/****************************************************************************** -* * * Paramètres : block = bloc dont les informations sont à consulter. * -* dest = bloc de code visé par la liaison (côté destination). * -* type = type de lien à construire. * +* count = nombre de ces origines. [OUT] * * * -* Description : Etablit un lien entre deux blocs de code. * +* Description : Fournit les détails des origines d'un bloc de code donné. * * * -* Retour : - * +* Retour : Liens déterminés vers des blocs de code d'origine. * * * * Remarques : - * * * ******************************************************************************/ -void g_code_block_link_with(GCodeBlock *block, GCodeBlock *dest, InstructionLinkType type) +block_link_t *g_code_block_get_sources(const GCodeBlock *block, size_t *count) { - block_link_t new_src; /* Nouveau lien à définir #1 */ - block_link_t new_dst; /* Nouveau lien à définir #2 */ - - /* Côté destination */ - - new_src.linked = block; - new_src.type = type; - - ref_block_link((&new_src)); - - /* Côté point de départ */ - - new_dst.linked = dest; - new_dst.type = type; - - ref_block_link((&new_dst)); - - /* Ajout dans le respect d'une cohérence globale */ - - g_code_block_lock_src(dest); - g_code_block_lock_dest(block); - - add_item_to_flat_array(&dest->from, &new_src, sizeof(block_link_t)); - - add_item_to_flat_array(&block->to, &new_dst, sizeof(block_link_t)); - - g_code_block_unlock_dest(block); - g_code_block_unlock_src(dest); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc de code dont les informations sont à traiter. * -* * -* Description : Supprime tous les liens établis avec d'autres blocs de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_code_block_delete_all_links(GCodeBlock *block) -{ - block_link_t *link_src; /* Lien à supprimer #2 */ - GCodeBlock *other; /* Bloc de l'autre bout */ - size_t count; /* Quantié de liens présents */ - size_t i; /* Boucle de parcours */ - block_link_t *link_dst; /* Lien à supprimer #1 */ - - /* Coté sources */ - - g_code_block_lock_src(block); + block_link_t *result; /* Détails présents à renvoyer */ + GCodeBlockClass *class; /* Classe des blocs de code */ - while (count_flat_array_items(block->from) > 0) + if (block->list == NULL) { - link_src = get_flat_array_item(block->from, 0, sizeof(block_link_t)); - - other = link_src->linked; - - g_code_block_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(block_link_t)); - - if (link_dst->linked == block && link_dst->type == link_src->type) - { - unref_block_link(link_dst); - - rem_item_from_flat_array(&other->to, i, sizeof(block_link_t)); - - break; - - } - - } - - assert(i < count); - - g_code_block_unlock_dest(other); - - unref_block_link(link_src); - - rem_item_from_flat_array(&block->from, 0, sizeof(block_link_t)); - + result = NULL; + *count = 0; } - g_code_block_unlock_src(block); - - /* Coté destinations */ - - g_code_block_lock_dest(block); - - while (count_flat_array_items(block->to) > 0) + else { - link_dst = get_flat_array_item(block->to, 0, sizeof(block_link_t)); - - other = link_dst->linked; - - g_code_block_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(block_link_t)); - - if (link_src->linked == block && link_src->type == link_dst->type) - { - unref_block_link(link_src); - - rem_item_from_flat_array(&other->from, i, sizeof(block_link_t)); - - break; - - } - - } - - assert(i < count); - - g_code_block_unlock_src(other); - - unref_block_link(link_dst); + class = G_CODE_BLOCK_GET_CLASS(block); - rem_item_from_flat_array(&block->to, 0, sizeof(block_link_t)); + result = class->get_src(block, block->list, count); } - g_code_block_unlock_dest(block); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc dont les informations sont à consulter. * -* * -* Description : Fournit la quantité de blocs de code pointant vers un autre. * -* * -* Retour : Nombre de ces origines. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_code_block_count_sources(const GCodeBlock *block) -{ - size_t result; /* Nombre de liens à renvoyer */ - - result = count_flat_array_items(block->from); - return result; } @@ -612,72 +405,34 @@ size_t g_code_block_count_sources(const GCodeBlock *block) /****************************************************************************** * * * Paramètres : block = bloc dont les informations sont à consulter. * -* index = indice de l'élément à retrouver. * +* count = nombre de ces destinations. [OUT] * * * -* Description : Fournit les détails d'une origine d'un bloc de code donné. * +* Description : Fournit les détails des destinations de bloc de code. * * * -* Retour : Lien déterminé vers un bloc de code d'origine. * +* Retour : Liens déterminés vers des blocs de code de destination. * * * * Remarques : - * * * ******************************************************************************/ -const block_link_t *g_code_block_get_source(GCodeBlock *block, size_t index) +block_link_t *g_code_block_get_destinations(const GCodeBlock *block, size_t *count) { block_link_t *result; /* Détails présents à renvoyer */ + GCodeBlockClass *class; /* Classe des blocs de code */ - result = get_flat_array_item(block->from, index, sizeof(block_link_t)); - - ref_block_link(result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc dont les informations sont à consulter. * -* * -* Description : Donne le nombre de blocs de code suivants dans le flot. * -* * -* Retour : Nombre de ces destinations. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_code_block_count_destinations(const GCodeBlock *block) -{ - size_t result; /* Nombre de liens à renvoyer */ - - result = count_flat_array_items(block->to); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc dont les informations sont à consulter. * -* index = indice de l'élément à retrouver. * -* * -* Description : Fournit les détails d'une destination de bloc de code. * -* * -* Retour : Lien déterminé vers un bloc de code de destination. * -* * -* Remarques : - * -* * -******************************************************************************/ + if (block->list == NULL) + { + result = NULL; + *count = 0; + } -const block_link_t *g_code_block_get_destination(GCodeBlock *block, size_t index) -{ - block_link_t *result; /* Détails présents à renvoyer */ + else + { + class = G_CODE_BLOCK_GET_CLASS(block); - result = get_flat_array_item(block->to, index, sizeof(block_link_t)); + result = class->get_dest(block, block->list, count); - ref_block_link(result); + } return result; @@ -755,11 +510,7 @@ static void g_block_list_dispose(GBlockList *list) size_t i; /* Boucle de parcours */ for (i = 0; i < list->count; i++) - if (list->blocks[i] != NULL) - { - g_code_block_delete_all_links(list->blocks[i]); - g_clear_object(&list->blocks[i]); - } + g_clear_object(&list->blocks[i]); G_OBJECT_CLASS(g_block_list_parent_class)->dispose(G_OBJECT(list)); @@ -806,7 +557,7 @@ GBlockList *g_block_list_new(size_t count) result = g_object_new(G_TYPE_BLOCK_LIST, NULL); - result->blocks = (GCodeBlock **)calloc(count, sizeof(GCodeBlock *)); + result->blocks = calloc(count, sizeof(GCodeBlock *)); result->count = count; @@ -859,6 +610,9 @@ void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index) list->blocks[index] = block; + block->list = list; + g_object_ref(G_OBJECT(list)); + g_code_block_set_index(block, index); } @@ -879,10 +633,6 @@ void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index) void g_block_list_resolve_links(const GBlockList *list) { - size_t i; /* Boucle de parcours */ - - for (i = 0; i < list->count; i++) - g_code_block_resolve_links(list->blocks[i], list); } |