From 16f07d7609b71e7cbbed0dce438ed94fb96d089e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 21 May 2017 23:32:06 +0200
Subject: Stored and deleted instruction hooks using the GObject facilities.

---
 ChangeLog                  |  6 ++++++
 src/arch/instruction-int.h |  2 --
 src/arch/instruction.c     | 32 +++++++++++++++++++++++++++++---
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bceb52b..836a798 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 17-05-21  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/arch/instruction-int.h:
+	* src/arch/instruction.c:
+	Store and delete instruction hooks using the GObject facilities.
+
+17-05-21  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/arch/arm/register.c:
 	* src/arch/arm/v7/core.c:
 	* src/arch/arm/v7/operands/coproc.c:
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index b62bba7..fb1f796 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -50,8 +50,6 @@ struct _GArchInstruction
 {
     GObject parent;                         /* A laisser en premier        */
 
-    const instr_hook_fc *hooks;             /* Traitements complémentaires */
-
     mrange_t range;                         /* Emplacement en mémoire      */
 
     flat_array_t *operands;                 /* Liste des opérandes         */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 8f2f262..bb98efb 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -35,6 +35,16 @@
 
 
 
+/* Accès aux décrochages */
+static const char *_hook_names[IPH_COUNT] = {
+
+    [IPH_FETCH] = "IPH_FETCH",
+    [IPH_LINK] = "IPH_LINK",
+    [IPH_POST] = "IPH_POST"
+
+};
+
+
 /* Initialise la classe générique des instructions. */
 static void g_arch_instruction_class_init(GArchInstructionClass *);
 
@@ -311,7 +321,10 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
 
 void g_arch_instruction_set_hooks(GArchInstruction *instr, const instr_hook_fc hooks[IPH_COUNT])
 {
-    instr->hooks = hooks;
+    InstrProcessHook i;                     /* Boucle de parcours          */
+
+    for (i = 0; i < IPH_COUNT; i++)
+        g_object_set_data(G_OBJECT(instr), _hook_names[i], hooks[i]);
 
 }
 
@@ -334,10 +347,23 @@ void g_arch_instruction_set_hooks(GArchInstruction *instr, const instr_hook_fc h
 
 void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GExeFormat *format)
 {
+    instr_hook_fc hook;
+
     assert(type < IPH_COUNT);
 
-    if (instr->hooks != NULL && instr->hooks[type] != NULL)
-        instr->hooks[type](instr, proc, context, format);
+    hook = g_object_get_data(G_OBJECT(instr), _hook_names[type]);
+
+    if (hook != NULL)
+    {
+        /**
+         * Comme ce genre d'appel n'est effectué normalement qu'une seule fois
+         * par instruction, on libère la mémoire au moment de cet unique appel.
+         */
+        g_object_set_data(G_OBJECT(instr), _hook_names[type], NULL);
+
+        hook(instr, proc, context, format);
+
+    }
 
 }
 
-- 
cgit v0.11.2-87-g4458