1use crate::{
2 instructions::InstructionProvider, item_or_result::FrameInitOrResult, EthFrame, FrameResult,
3 ItemOrResult, PrecompileProvider,
4};
5use auto_impl::auto_impl;
6use context::{ContextTr, Database, Evm, FrameStack};
7use context_interface::context::ContextError;
8use interpreter::{interpreter::EthInterpreter, interpreter_action::FrameInit, InterpreterResult};
9
10pub type ContextDbError<CTX> = ContextError<ContextTrDbError<CTX>>;
12
13pub type ContextTrDbError<CTX> = <<CTX as ContextTr>::Db as Database>::Error;
15
16pub type FrameInitResult<'a, F> = ItemOrResult<&'a mut F, <F as FrameTr>::FrameResult>;
18
19#[auto_impl(&mut, Box)]
21pub trait FrameTr {
22 type FrameResult: Into<FrameResult>;
24 type FrameInit: Into<FrameInit>;
26}
27
28#[auto_impl(&mut, Box)]
32pub trait EvmTr {
33 type Context: ContextTr;
35 type Instructions: InstructionProvider;
37 type Precompiles: PrecompileProvider<Self::Context>;
39 type Frame: FrameTr;
41
42 fn ctx(&mut self) -> &mut Self::Context;
44
45 fn ctx_mut(&mut self) -> &mut Self::Context {
47 self.ctx()
48 }
49
50 fn ctx_ref(&self) -> &Self::Context;
52
53 fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions);
56
57 fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles);
60
61 fn frame_stack(&mut self) -> &mut FrameStack<Self::Frame>;
63
64 fn frame_init(
66 &mut self,
67 frame_input: <Self::Frame as FrameTr>::FrameInit,
68 ) -> Result<FrameInitResult<'_, Self::Frame>, ContextDbError<Self::Context>>;
69
70 fn frame_run(
74 &mut self,
75 ) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<Self::Context>>;
76
77 fn frame_return_result(
80 &mut self,
81 result: <Self::Frame as FrameTr>::FrameResult,
82 ) -> Result<Option<<Self::Frame as FrameTr>::FrameResult>, ContextDbError<Self::Context>>;
83}
84
85impl<CTX, INSP, I, P> EvmTr for Evm<CTX, INSP, I, P, EthFrame<EthInterpreter>>
86where
87 CTX: ContextTr,
88 I: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
89 P: PrecompileProvider<CTX, Output = InterpreterResult>,
90{
91 type Context = CTX;
92 type Instructions = I;
93 type Precompiles = P;
94 type Frame = EthFrame<EthInterpreter>;
95
96 #[inline]
97 fn ctx(&mut self) -> &mut Self::Context {
98 &mut self.ctx
99 }
100
101 #[inline]
102 fn ctx_ref(&self) -> &Self::Context {
103 &self.ctx
104 }
105
106 #[inline]
107 fn frame_stack(&mut self) -> &mut FrameStack<Self::Frame> {
108 &mut self.frame_stack
109 }
110
111 #[inline]
113 fn frame_init(
114 &mut self,
115 frame_input: <Self::Frame as FrameTr>::FrameInit,
116 ) -> Result<FrameInitResult<'_, Self::Frame>, ContextDbError<CTX>> {
117 let is_first_init = self.frame_stack.index().is_none();
118 let new_frame = if is_first_init {
119 self.frame_stack.start_init()
120 } else {
121 self.frame_stack.get_next()
122 };
123
124 let ctx = &mut self.ctx;
125 let precompiles = &mut self.precompiles;
126 let res = Self::Frame::init_with_context(new_frame, ctx, precompiles, frame_input)?;
127
128 Ok(res.map_frame(|token| {
129 if is_first_init {
130 self.frame_stack.end_init(token);
131 } else {
132 self.frame_stack.push(token);
133 }
134 self.frame_stack.get()
135 }))
136 }
137
138 #[inline]
140 fn frame_run(&mut self) -> Result<FrameInitOrResult<Self::Frame>, ContextDbError<CTX>> {
141 let frame = self.frame_stack.get();
142 let context = &mut self.ctx;
143 let instructions = &mut self.instruction;
144
145 let action = frame
146 .interpreter
147 .run_plain(instructions.instruction_table(), context);
148
149 frame.process_next_action(context, action).inspect(|i| {
150 if i.is_result() {
151 frame.set_finished(true);
152 }
153 })
154 }
155
156 #[inline]
158 fn frame_return_result(
159 &mut self,
160 result: <Self::Frame as FrameTr>::FrameResult,
161 ) -> Result<Option<<Self::Frame as FrameTr>::FrameResult>, ContextDbError<Self::Context>> {
162 if self.frame_stack.get().is_finished() {
163 self.frame_stack.pop();
164 }
165 if self.frame_stack.index().is_none() {
166 return Ok(Some(result));
167 }
168 self.frame_stack
169 .get()
170 .return_result::<_, ContextDbError<Self::Context>>(&mut self.ctx, result)?;
171 Ok(None)
172 }
173
174 #[inline]
175 fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) {
176 (&mut self.ctx, &mut self.instruction)
177 }
178
179 #[inline]
180 fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) {
181 (&mut self.ctx, &mut self.precompiles)
182 }
183}