Skip to main content

neo_decompiler/decompiler/analysis/call_graph/
model.rs

1use serde::Serialize;
2
3use super::super::MethodRef;
4
5/// A resolved call target extracted from the instruction stream.
6#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
7#[non_exhaustive]
8pub enum CallTarget {
9    /// Direct call into the same script (CALL/CALL_L).
10    Internal {
11        /// Callee method resolved from the target offset.
12        method: MethodRef,
13    },
14    /// Call to an entry in the NEF method-token table (CALLT).
15    MethodToken {
16        /// Index into the NEF `method_tokens` table.
17        index: u16,
18        /// Script hash (little-endian) for the called contract.
19        hash_le: String,
20        /// Script hash (big-endian) for the called contract.
21        hash_be: String,
22        /// Target method name.
23        method: String,
24        /// Declared parameter count.
25        parameters_count: u16,
26        /// Whether the target method has a return value.
27        has_return_value: bool,
28        /// Call flags bitfield.
29        call_flags: u8,
30        /// Human-readable call flags including unsupported bits.
31        call_flags_description: String,
32    },
33    /// System call (SYSCALL).
34    Syscall {
35        /// Syscall identifier (little-endian u32).
36        hash: u32,
37        /// Resolved syscall name when known.
38        name: Option<String>,
39        /// Whether the syscall is known to push a value.
40        returns_value: bool,
41    },
42    /// Indirect call (e.g., CALLA) where the destination cannot be resolved statically.
43    Indirect {
44        /// Opcode mnemonic (`CALLA` or similar).
45        opcode: String,
46        /// Optional operand value (when present).
47        operand: Option<u16>,
48    },
49    /// A CALL/CALL_L target that could not be resolved to a valid offset.
50    UnresolvedInternal {
51        /// Computed target offset (may be negative when malformed).
52        target: isize,
53    },
54}
55
56/// One call edge in the call graph.
57#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
58pub struct CallEdge {
59    /// Caller method containing the call instruction.
60    pub caller: MethodRef,
61    /// Bytecode offset of the call instruction.
62    pub call_offset: usize,
63    /// Opcode mnemonic of the call instruction (e.g., `CALL_L`, `SYSCALL`).
64    pub opcode: String,
65    /// Resolved target.
66    pub target: CallTarget,
67}
68
69/// Call graph for a decompiled script.
70#[derive(Debug, Clone, Default, Serialize)]
71pub struct CallGraph {
72    /// Known methods (manifest-defined plus synthetic internal targets).
73    pub methods: Vec<MethodRef>,
74    /// Call edges extracted from the instruction stream.
75    pub edges: Vec<CallEdge>,
76}