hebi 0.4.0

A dynamic scripting language
Documentation
macro_rules! read_opcode {
  ($ip:ident, $end:ident) => {
    unsafe {
      debug_assert!($ip < $end, "unexpected end of bytecode stream");
      let opcode = $ip.read();
      $ip = $ip.add(1);

      debug_assert!(
        $crate::internal::bytecode::opcode::Opcode::try_from(opcode).is_ok(),
        "illegal instruction"
      );
      ::core::mem::transmute::<u8, Opcode>(opcode)
    }
  };
}

#[doc(hidden)]
#[inline]
pub unsafe fn __read_tuple<const N: usize, T: crate::internal::bytecode::operands::Operand>(
  ip: *mut u8,
  width: crate::internal::bytecode::operands::Width,
) -> T {
  let len = N * width as usize;
  let buf = &*std::ptr::slice_from_raw_parts(ip, len);
  T::decode(buf, width)
}

macro_rules! read_operands {
  ($T:ident, $ip:ident, $end:ident, $width:ident) => {{
    type Operands =
      <$crate::internal::bytecode::opcode::symbolic::$T as $crate::internal::bytecode::opcode::Operands>::Operands;
    const LENGTH: usize = <Operands as $crate::util::TupleLength>::LENGTH;

    if LENGTH > 0 {
      unsafe {
        debug_assert!($ip < $end, "unexpected end of bytecode stream");

        let operands = $crate::internal::vm::dispatch::macros::__read_tuple::<LENGTH, Operands>($ip, $width);
        $ip = $ip.add(LENGTH * ($width as usize));
        $width = Width::Normal;
        operands
      }
    } else {
      Operands::default()
    }
  }};
}

macro_rules! get_pc {
  ($ip:ident, $code:ident) => {
    ($ip as usize) - ($code.as_ptr() as *mut u8 as usize)
  };
}