ordinary-utils 0.6.0-pre.2

Utils for Ordinary
Documentation
// Copyright (C) 2026 Ordinary Labs, LLC.
//
// SPDX-License-Identifier: AGPL-3.0-only

use std::error::Error;
use wasi_common::WasiCtx;
use wasmtime::{AsContext, AsContextMut, Caller, Extern};

pub fn read_mem(
    caller: &mut Caller<'_, WasiCtx>,
    ptr: i32,
    buf: &mut [u8],
) -> Result<(), Box<dyn Error>> {
    let Some(Extern::Memory(mem)) = caller.get_export("memory") else {
        return Err("no mem".into());
    };

    mem.read(caller.as_context_mut(), ptr as usize, buf)?;
    Ok(())
}

pub fn write_mem(caller: &mut Caller<'_, WasiCtx>, bytes: &[u8]) -> Option<i64> {
    let alloc = match caller.get_export("alloc") {
        Some(Extern::Func(malloc)) => match malloc.typed::<i32, i32>(caller.as_context()) {
            Ok(malloc) => malloc,
            Err(_) => return None,
        },
        _ => return None,
    };

    let len = bytes.len();

    let Ok(params) = i32::try_from(len) else {
        return None;
    };

    let Ok(ptr) = alloc.call(caller.as_context_mut(), params) else {
        return None;
    };

    let Some(Extern::Memory(mem)) = caller.get_export("memory") else {
        return None;
    };

    match mem.write(caller.as_context_mut(), ptr as usize, bytes) {
        Ok(()) => {}
        Err(_) => return None,
    }

    let ptr64 = i64::from(ptr) << 32;
    let Ok(len64) = i64::try_from(len) else {
        return None;
    };

    Some(ptr64 | len64)
}