mod decode;
use crate::vm::{Exception, InstructionLen, InstructionVtable, Vm};
use std::fmt::{self, Display, Formatter};
#[derive(Debug)]
pub struct Instruction {
data: [u16; InstructionLen::MAX.get()],
vtable: &'static InstructionVtable,
}
impl Instruction {
#[inline(always)]
#[must_use]
pub const fn len(&self) -> InstructionLen {
self.vtable.len
}
}
const impl Clone for Instruction {
#[inline]
fn clone(&self) -> Self {
Self {
data: self.data,
vtable: self.vtable,
}
}
}
impl Display for Instruction {
#[inline(always)]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{:04x}", self.data[0])?;
for word in self.data.iter().take(self.len().get()).skip(1) {
write!(f, " {word:04x}")?;
}
f.write_str(": ")?;
(self.vtable.fmt)(self, f)
}
}
impl Fn<(&mut Vm,)> for Instruction {
extern "rust-call" fn call(&self, (vm,): (&mut Vm,)) -> Self::Output {
(self.vtable.exec)(self, vm)
}
}
impl FnMut<(&mut Vm,)> for Instruction {
extern "rust-call" fn call_mut(&mut self, args: (&mut Vm,)) -> Self::Output {
self.call(args)
}
}
impl FnOnce<(&mut Vm,)> for Instruction {
type Output = Result<(), Exception>;
#[inline]
extern "rust-call" fn call_once(self, args: (&mut Vm,)) -> Self::Output {
self.call(args)
}
}