diff options
Diffstat (limited to 'src/decomp/expr/call.c')
-rw-r--r-- | src/decomp/expr/call.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/decomp/expr/call.c b/src/decomp/expr/call.c index e518c6f..ed1c43a 100644 --- a/src/decomp/expr/call.c +++ b/src/decomp/expr/call.c @@ -60,6 +60,12 @@ static void g_routine_call_class_init(GRoutineCallClass *); /* Initialise une instance d'appel à une routine quelconque. */ static void g_routine_call_init(GRoutineCall *); +/* Visite un ensemble hiérarchique d'instructions décompilées. */ +static bool g_routine_call_visit(GRoutineCall *, dec_instr_visitor_cb, DecInstrVisitFlags, void *); + +/* Remplace une instruction décompilée par une autre. */ +static bool g_routine_call_replace(GRoutineCall *, GDecInstruction *, GDecInstruction *); + /* Imprime pour l'écran un version humaine d'une expression. */ static GBufferLine *g_routine_call_print(const GRoutineCall *, GCodeBuffer *, GBufferLine *, GLangOutput *); @@ -105,6 +111,8 @@ static void g_routine_call_init(GRoutineCall *expr) instr = G_DEC_INSTRUCTION(expr); + instr->visit = (dec_instr_visit_fc)g_routine_call_visit; + instr->replace = (dec_instr_replace_fc)g_routine_call_replace; instr->print = (dec_instr_print_fc)g_routine_call_print; } @@ -137,6 +145,78 @@ GDecInstruction *g_routine_call_new(GBinRoutine *routine) /****************************************************************************** * * +* Paramètres : call = première instruction à venir visiter. * +* callback = procédure à appeler à chaque instruction visitée. * +* flags = moments des appels à réaliser en retour. * +* data = données quelconques associées au visiteur. * +* * +* Description : Visite un ensemble hiérarchique d'instructions décompilées. * +* * +* Retour : true si le parcours a été jusqu'à son terme, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_routine_call_visit(GRoutineCall *call, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < call->count && result; i++) + result = g_dec_instruction_visit(call->args[i], callback, flags, data); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : call = première instruction à venir ausculter. * +* old = instruction décompilée à venir remplacer. * +* new = instruction décompilée à utiliser dorénavant. * +* * +* Description : Remplace une instruction décompilée par une autre. * +* * +* Retour : true si un remplacement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_routine_call_replace(GRoutineCall *call, GDecInstruction *old, GDecInstruction *new) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = false; + + for (i = 0; i < call->count; i++) + { + if (call->args[i] == old) + { + g_object_unref(G_OBJECT(call->args[i])); + g_object_ref(G_OBJECT(new)); + call->args[i] = new; + + result = true; + + } + else + result |= g_dec_instruction_replace(call->args[i], old, new); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : call = expression à transcrire en version humaine. * * buffer = tampon où doit se réaliser l'insertion. * * line = ligne d'impression prête à emploi ou NULL. * |