use crate::error::{VmError, VmResult};
use crate::native::{NativeRegistry, MAX_NATIVE_ARGS};
use crate::state::VmState;
pub fn handle_native_call(state: &mut VmState, registry: &NativeRegistry) -> VmResult<()> {
let func_id = state.read_u8()?;
let arg_count = state.read_u8()? as usize;
if arg_count > MAX_NATIVE_ARGS {
return Err(VmError::NativeTooManyArgs);
}
let mut args = [0u64; MAX_NATIVE_ARGS];
for i in (0..arg_count).rev() {
args[i] = state.pop()?;
}
if let Some(native_fn) = state.get_native_fn(func_id as usize) {
let result = native_fn(&args[..arg_count]);
return state.push(result);
}
let result = registry.call(func_id, &args[..arg_count])?;
state.push(result)
}
pub fn handle_native_read(state: &mut VmState) -> VmResult<()> {
let offset = state.read_u16()? as usize;
let value = state.read_input_u64(offset)?;
state.push(value)
}
pub fn handle_native_write(state: &mut VmState) -> VmResult<()> {
let _offset = state.read_u16()?;
let value = state.pop()?;
state.output.push(value as u8);
Ok(())
}
pub fn handle_input_len(state: &mut VmState) -> VmResult<()> {
let len = state.input_len() as u64;
state.push(len)
}