fuel_vm/interpreter/
ecal.rs1use fuel_asm::{
4 PanicReason,
5 RegId,
6};
7
8use crate::{
9 constraints::reg_key::{
10 SystemRegisters,
11 split_registers,
12 },
13 error::SimpleResult,
14 interpreter::NotSupportedEcal,
15};
16
17use super::{
18 Interpreter,
19 Memory,
20 internal::inc_pc,
21};
22
23pub trait EcalHandler: Clone
29where
30 Self: Sized,
31{
32 const INC_PC: bool = true;
35
36 fn ecal<M, S, Tx, V>(
38 vm: &mut Interpreter<M, S, Tx, Self, V>,
39 a: RegId,
40 b: RegId,
41 c: RegId,
42 d: RegId,
43 ) -> SimpleResult<()>
44 where
45 M: Memory;
46}
47
48impl EcalHandler for NotSupportedEcal {
50 fn ecal<M, S, Tx, V>(
51 _: &mut Interpreter<M, S, Tx, Self, V>,
52 _: RegId,
53 _: RegId,
54 _: RegId,
55 _: RegId,
56 ) -> SimpleResult<()> {
57 Err(PanicReason::EcalError)?
58 }
59}
60
61impl<M, S, Tx, Ecal, V> Interpreter<M, S, Tx, Ecal, V>
62where
63 M: Memory,
64 Ecal: EcalHandler,
65{
66 pub(crate) fn external_call(
68 &mut self,
69 a: RegId,
70 b: RegId,
71 c: RegId,
72 d: RegId,
73 ) -> SimpleResult<()> {
74 Ecal::ecal(self, a, b, c, d)?;
75 let (SystemRegisters { pc, .. }, _) = split_registers(&mut self.registers);
76 if Ecal::INC_PC {
77 Ok(inc_pc(pc)?)
78 } else {
79 Ok(())
80 }
81 }
82}
83
84impl<M, S, Tx, Ecal, V> Interpreter<M, S, Tx, Ecal, V>
85where
86 Ecal: EcalHandler,
87{
88 pub fn ecal_state(&self) -> &Ecal {
90 &self.ecal_state
91 }
92
93 pub fn ecal_state_mut(&mut self) -> &mut Ecal {
95 &mut self.ecal_state
96 }
97}