Skip to content

Instantly share code, notes, and snippets.

@matklad
Created February 18, 2022 10:26
Show Gist options
  • Save matklad/dce8ac9787571a157cace6f792c2ee46 to your computer and use it in GitHub Desktop.
Save matklad/dce8ac9787571a157cace6f792c2ee46 to your computer and use it in GitHub Desktop.
pub trait Handler: Sized {
fn address(&mut self, state: &mut Machine, opcode: Opcode, position: usize) -> Control;
}
type OpFn<H> = fn(this: &mut H, state: &mut Machine, opcode: Opcode, position: usize) -> Control;
// We would like to write this, but Rust's const-eval is not good enough for that yet :(
// const fn mk_table<H: Handler>() -> [OpFn<H>; 256] { }
// So, we have to express this as type-level function (trait)
trait MkTable<H: Handler> {
const TABLE: [OpFn<H>; 256];
}
struct OpTable<H: Handler>(PhantomData<H>);
impl<H: Handler> MkTable<H> for OpTable<H> {
const TABLE: [OpFn<H>; 256] = {
let mut res: [OpFn<H>; 256] = [|_, _, _, _| Control::Exit(ExitError::OutOfGas.into()); 256];
// Built-in op-codes
res[Opcode::STOP.as_usize()] = (|_, s, o, p| eval_stop(s, o, p)) as OpFn<H>;
// Customizable op-codes
res[Opcode::ADDRESS.as_usize()] = H::address;
res
};
}
#[inline]
pub fn eval_with<H: Handler>(
h: &mut H,
state: &mut Machine,
opcode: Opcode,
position: usize,
) -> Control {
OpTable::<H>::TABLE[opcode.as_usize()](h, state, opcode, position)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment