1use alloc::{
6 borrow::ToOwned,
7 vec::Vec,
8};
9
10use crate::{
11 call::CallFrame,
12 consts::*,
13 interpreter::{
14 InitialBalances,
15 Interpreter,
16 },
17};
18use educe::Educe;
19
20use crate::interpreter::{
21 Memory,
22 MemoryInstance,
23};
24use fuel_tx::ScriptExecutionResult;
25use fuel_types::{
26 ContractId,
27 Word,
28};
29
30#[derive(Educe)]
31#[educe(Debug)]
32pub struct Backtrace {
34 call_stack: Vec<CallFrame>,
35 contract: ContractId,
36 registers: [Word; VM_REGISTER_COUNT],
37 memory: MemoryInstance,
38 result: ScriptExecutionResult,
39 initial_balances: InitialBalances,
40}
41
42impl Backtrace {
43 pub fn from_vm_error<M, S, Tx, Ecal>(
47 vm: &Interpreter<M, S, Tx, Ecal>,
48 result: ScriptExecutionResult,
49 ) -> Self
50 where
51 M: Memory,
52 {
53 let call_stack = vm.call_stack().to_owned();
54 let contract = vm.internal_contract().unwrap_or_default();
55 let memory = vm.memory().clone();
56 let initial_balances = vm.initial_balances().clone();
57 let mut registers = [0; VM_REGISTER_COUNT];
58
59 registers.copy_from_slice(vm.registers());
60
61 Self {
62 call_stack,
63 contract,
64 registers,
65 memory,
66 result,
67 initial_balances,
68 }
69 }
70
71 pub fn call_stack(&self) -> &[CallFrame] {
73 self.call_stack.as_slice()
74 }
75
76 pub const fn contract(&self) -> &ContractId {
78 &self.contract
79 }
80
81 pub const fn registers(&self) -> &[Word] {
83 &self.registers
84 }
85
86 pub fn memory(&self) -> &MemoryInstance {
88 &self.memory
89 }
90
91 pub const fn result(&self) -> &ScriptExecutionResult {
93 &self.result
94 }
95
96 pub const fn initial_balances(&self) -> &InitialBalances {
98 &self.initial_balances
99 }
100
101 pub fn into_inner(
103 self,
104 ) -> (
105 Vec<CallFrame>,
106 ContractId,
107 [Word; VM_REGISTER_COUNT],
108 MemoryInstance,
109 ScriptExecutionResult,
110 InitialBalances,
111 ) {
112 let Self {
113 call_stack,
114 contract,
115 registers,
116 memory,
117 result,
118 initial_balances,
119 } = self;
120
121 (
122 call_stack,
123 contract,
124 registers,
125 memory,
126 result,
127 initial_balances,
128 )
129 }
130}