1 /// Object-oriented wrapper of Capstone's instruction detail
2 module capstone.detail;
3 
4 import capstone.capstone: Capstone;
5 import capstone.internal: cs_detail;
6 import capstone.register;
7 import capstone.instructiongroup;
8 
9 /// Instruction detail 
10 abstract class Detail {
11 private:
12     const Capstone cs;
13     cs_detail* internal;
14 
15 public:
16     /// Registers implicitly read by this instruction
17 	const(Register)[] regsRead() const;
18     /// Registers implicitly modified by this instruction
19 	const(Register)[] regsWrite() const;
20     /// The groups this instruction belongs to
21 	const(InstructionGroup)[] groups() const;
22 
23     private this(in Capstone cs, cs_detail* internal){
24         this.cs = cs;
25         this.internal = internal;
26     }
27 }
28 
29 /** Class template that encapsulates architecture-specific instruction detail
30 
31 Note that all architecture-specific instances, like `X86Detail`, instantiate and derive from this one.
32 */
33 abstract class DetailImpl(TRegister, TInstructionGroup, TInstructionDetail) : Detail {
34     import std.array: array;
35     import std.algorithm: map;
36 
37     /// Architecture-specific instruction detail
38     TInstructionDetail archSpecific;
39     /// Convenience-alias making `archSpecific`'s members directly accessible from this
40     alias archSpecific this;
41 
42     package this(in Capstone cs, cs_detail* internal){
43         super(cs, internal);
44         archSpecific = TInstructionDetail(cs, internal.arch_detail);
45     }
46 
47 	override TRegister[] regsRead() const {return internal.regs_read[0..internal.regs_read_count].map!(reg => new TRegister(cs, reg)).array;}
48 	override TRegister[] regsWrite() const {return internal.regs_write[0..internal.regs_write_count].map!(reg => new TRegister(cs, reg)).array;}
49 	override TInstructionGroup[] groups() const {return internal.groups[0..internal.groups_count].map!(grp => new TInstructionGroup(cs, grp)).array;}
50 }