use std::sync::Arc;
use wapc::ModuleState;
use wasm3::CallContext;
pub(crate) fn host_call(
ctx: &CallContext,
bd_ptr: i32,
bd_len: i32,
ns_ptr: i32,
ns_len: i32,
op_ptr: i32,
op_len: i32,
ptr: i32,
len: i32,
host: Arc<ModuleState>,
) -> i32 {
let vec = get_vec_from_memory(ctx, ptr, len);
let bd_vec = get_vec_from_memory(ctx, bd_ptr, bd_len);
let bd = ::std::str::from_utf8(&bd_vec).unwrap();
let ns_vec = get_vec_from_memory(ctx, ns_ptr, ns_len);
let ns = ::std::str::from_utf8(&ns_vec).unwrap();
let op_vec = get_vec_from_memory(ctx, op_ptr, op_len);
let op = ::std::str::from_utf8(&op_vec).unwrap();
let result = host.do_host_call(bd, ns, op, &vec);
if let Ok(r) = result {
r
} else {
0
}
}
pub(crate) fn guest_request(ctx: &CallContext, op_ptr: i32, ptr: i32, host: Arc<ModuleState>) {
if let Some(inv) = host.get_guest_request() {
write_bytes_to_memory(ctx, ptr, &inv.msg);
write_bytes_to_memory(ctx, op_ptr, &inv.operation.as_bytes());
}
}
pub(crate) fn host_response(ctx: &CallContext, ptr: i32, host: Arc<ModuleState>) {
if let Some(ref r) = host.get_host_response() {
write_bytes_to_memory(ctx, ptr, &r);
}
}
pub(crate) fn host_response_length(_ctx: &CallContext, host: Arc<ModuleState>) -> i32 {
host.get_host_response().unwrap_or(vec![]).len() as _
}
pub(crate) fn console_log(ctx: &CallContext, ptr: i32, len: i32, host: Arc<ModuleState>) {
let vec = get_vec_from_memory(ctx, ptr, len);
let msg = std::str::from_utf8(&vec).unwrap();
host.do_console_log(msg);
}
pub(crate) fn guest_response(ctx: &CallContext, ptr: i32, len: i32, host: Arc<ModuleState>) {
let vec = get_vec_from_memory(ctx, ptr, len);
host.set_guest_response(vec);
}
pub(crate) fn guest_error(ctx: &CallContext, ptr: i32, len: i32, host: Arc<ModuleState>) {
let vec = get_vec_from_memory(ctx, ptr, len);
host.set_guest_error(String::from_utf8(vec).unwrap());
}
pub(crate) fn host_error(ctx: &CallContext, ptr: i32, host: Arc<ModuleState>) {
if let Some(ref e) = host.get_host_error() {
write_bytes_to_memory(ctx, ptr, e.as_bytes());
}
}
pub(crate) fn host_error_length(host: Arc<ModuleState>) -> i32 {
host.get_host_error().unwrap_or("".to_string()).len() as _
}
fn get_vec_from_memory(ctx: &CallContext, ptr: i32, len: i32) -> Vec<u8> {
let data = unsafe { &*ctx.memory() };
data[ptr as usize..][..len as usize].to_vec()
}
fn write_bytes_to_memory(ctx: &CallContext, ptr: i32, slice: &[u8]) {
unsafe {
(&mut *ctx.memory_mut())[ptr as usize..][..slice.len()].copy_from_slice(slice);
};
}