use crate::{instructions::InstructionProvider, PrecompileProvider};
use auto_impl::auto_impl;
use context::{ContextTr, Evm};
use interpreter::{Interpreter, InterpreterAction, InterpreterTypes};
#[auto_impl(&mut, Box)]
pub trait EvmTr {
type Context: ContextTr;
type Instructions: InstructionProvider;
type Precompiles: PrecompileProvider<Self::Context>;
fn run_interpreter(
&mut self,
interpreter: &mut Interpreter<
<Self::Instructions as InstructionProvider>::InterpreterTypes,
>,
) -> <<Self::Instructions as InstructionProvider>::InterpreterTypes as InterpreterTypes>::Output;
fn ctx(&mut self) -> &mut Self::Context;
fn ctx_mut(&mut self) -> &mut Self::Context {
self.ctx()
}
fn ctx_ref(&self) -> &Self::Context;
fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions);
fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles);
}
impl<CTX, INSP, I, P> EvmTr for Evm<CTX, INSP, I, P>
where
CTX: ContextTr,
I: InstructionProvider<
Context = CTX,
InterpreterTypes: InterpreterTypes<Output = InterpreterAction>,
>,
P: PrecompileProvider<CTX>,
{
type Context = CTX;
type Instructions = I;
type Precompiles = P;
#[inline]
fn run_interpreter(
&mut self,
interpreter: &mut Interpreter<
<Self::Instructions as InstructionProvider>::InterpreterTypes,
>,
) -> <<Self::Instructions as InstructionProvider>::InterpreterTypes as InterpreterTypes>::Output
{
let context = &mut self.ctx;
let instructions = &mut self.instruction;
interpreter.run_plain(instructions.instruction_table(), context)
}
#[inline]
fn ctx(&mut self) -> &mut Self::Context {
&mut self.ctx
}
#[inline]
fn ctx_ref(&self) -> &Self::Context {
&self.ctx
}
#[inline]
fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) {
(&mut self.ctx, &mut self.instruction)
}
#[inline]
fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) {
(&mut self.ctx, &mut self.precompiles)
}
}