fuel_vm/interpreter/
ecal.rs1use fuel_asm::{
4 PanicReason,
5 RegId,
6};
7
8use crate::{
9 constraints::reg_key::{
10 split_registers,
11 SystemRegisters,
12 },
13 error::SimpleResult,
14 interpreter::NotSupportedEcal,
15};
16
17use super::{
18 internal::inc_pc,
19 Interpreter,
20 Memory,
21};
22
23pub trait EcalHandler: Clone
25where
26 Self: Sized,
27{
28 const INC_PC: bool = true;
31
32 fn ecal<M, S, Tx>(
34 vm: &mut Interpreter<M, S, Tx, Self>,
35 a: RegId,
36 b: RegId,
37 c: RegId,
38 d: RegId,
39 ) -> SimpleResult<()>
40 where
41 M: Memory;
42}
43
44impl EcalHandler for NotSupportedEcal {
46 fn ecal<M, S, Tx>(
47 _: &mut Interpreter<M, S, Tx, Self>,
48 _: RegId,
49 _: RegId,
50 _: RegId,
51 _: RegId,
52 ) -> SimpleResult<()> {
53 Err(PanicReason::EcalError)?
54 }
55}
56
57#[derive(Debug, Clone, Copy, Default)]
59pub struct PredicateErrorEcal;
60
61impl EcalHandler for PredicateErrorEcal {
63 fn ecal<M, S, Tx>(
64 _vm: &mut Interpreter<M, S, Tx, Self>,
65 _: RegId,
66 _: RegId,
67 _: RegId,
68 _: RegId,
69 ) -> SimpleResult<()> {
70 Err(PanicReason::ContractInstructionNotAllowed)?
71 }
72}
73
74impl<M, S, Tx, Ecal> Interpreter<M, S, Tx, Ecal>
75where
76 M: Memory,
77 Ecal: EcalHandler,
78{
79 pub(crate) fn external_call(
81 &mut self,
82 a: RegId,
83 b: RegId,
84 c: RegId,
85 d: RegId,
86 ) -> SimpleResult<()> {
87 Ecal::ecal(self, a, b, c, d)?;
88 let (SystemRegisters { pc, .. }, _) = split_registers(&mut self.registers);
89 if Ecal::INC_PC {
90 Ok(inc_pc(pc)?)
91 } else {
92 Ok(())
93 }
94 }
95}
96
97impl<M, S, Tx, Ecal> Interpreter<M, S, Tx, Ecal>
98where
99 Ecal: EcalHandler,
100{
101 pub fn ecal_state(&self) -> &Ecal {
103 &self.ecal_state
104 }
105
106 pub fn ecal_state_mut(&mut self) -> &mut Ecal {
108 &mut self.ecal_state
109 }
110}