extern crate self as arora_module;
pub use arora_module_macros::{contract, declare_module, export, module, module_from_header};
pub use arora_types::module::declared::{AroraFunction, AroraModule};
#[doc(hidden)]
pub mod __rt {
pub use arora_buffers as buffers;
pub use arora_types as types;
#[cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))]
pub use wit_bindgen;
pub fn keep_result(result: Result<Vec<u8>, String>) -> usize {
use std::cell::RefCell;
thread_local! {
static LATEST: RefCell<Box<[u8]>> = RefCell::new(Box::default());
}
let error = |message: &str| {
let mut writer = arora_buffers::BufferWriter::new();
writer.add_error(message);
writer.finalize()
};
let buffer = match result {
Ok(buffer) if arora_buffers::well_formed(&buffer).is_ok() => buffer.into_boxed_slice(),
Ok(_) => error("the result is not an Arora Buffer"),
Err(message) => error(&message),
};
let address = buffer.as_ptr() as usize;
LATEST.with(|latest| *latest.borrow_mut() = buffer);
address
}
#[cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))]
pub mod engine {
use super::keep_result;
use crate::component::arora::module::host;
use crate::component::Id;
unsafe fn id_at(address: usize) -> Id {
let bytes = unsafe { *(address as *const [u8; 16]) };
let (hi, lo) = arora_types::Uuid::from_bytes(bytes).as_u64_pair();
Id { hi, lo }
}
unsafe fn buffer_at<'a>(address: usize) -> &'a [u8] {
unsafe {
let size = u32::from_le_bytes(*(address as *const [u8; 4])) as usize;
std::slice::from_raw_parts(address as *const u8, size)
}
}
pub unsafe extern "C" fn arora_dispatch(
module_id: usize,
method_id: usize,
arg: usize,
) -> usize {
let (module, method, arg) =
unsafe { (id_at(module_id), id_at(method_id), buffer_at(arg)) };
keep_result(host::dispatch(module, method, arg))
}
pub unsafe extern "C" fn arora_dispatch_indirect(callable_id: u64) -> usize {
keep_result(host::dispatch_indirect(callable_id))
}
}
}
#[macro_export]
macro_rules! artifact {
($($($segment:ident)::+),+ $(,)?) => {
#[cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))]
const _: () = {
struct Component;
impl $crate::component::Guest for Component {
fn functions() -> ::std::vec::Vec<$crate::component::Id> {
let mut functions = ::std::vec::Vec::new();
$(
for id in $($segment)::+::function_ids() {
let (hi, lo) = id.as_u64_pair();
functions.push($crate::component::Id { hi, lo });
}
)+
functions
}
fn dispatch(
method: $crate::component::Id,
arg: ::std::vec::Vec<u8>,
) -> ::std::result::Result<::std::vec::Vec<u8>, ::std::string::String> {
let method = $crate::__rt::types::Uuid::from_u64_pair(method.hi, method.lo);
$(
if let ::std::option::Option::Some(result) = $($segment)::+::dispatch_buffer(method, &arg) {
return result.map(::std::vec::Vec::from);
}
)+
::std::result::Result::Err(::std::format!(
"the artifact exports no function {method}"
))
}
}
$crate::component::export!(Component);
};
};
}
#[cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))]
pub mod component {
wit_bindgen::generate!({
world: "module",
path: "wit",
pub_export_macro: true,
default_bindings_module: "::arora_module::component",
runtime_path: "::arora_module::__rt::wit_bindgen::rt",
});
}