#![allow(bad_style)]
#![deny(dead_code)]
use std::ffi::c_void;
use std::mem;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
pub type wasm_name_t = wasm_byte_vec_t;
pub type wasm_valkind_t = u8;
pub type wasm_externkind_t = u8;
pub type wasm_message_t = wasm_name_t;
pub type wasm_func_callback_with_env_t = Option<
unsafe extern "C" fn(
env: *mut c_void,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> *mut wasm_trap_t,
>;
pub const WASM_I32: wasm_valkind_t = 0;
pub const WASM_EXTERN_FUNC: wasm_externkind_t = 0;
pub const WASM_EXTERN_MEMORY: wasm_externkind_t = 3;
#[repr(C)]
pub struct wasm_byte_vec_t {
pub size: usize,
pub data: *mut u8,
}
#[repr(C)]
pub struct wasm_extern_vec_t {
pub size: usize,
pub data: *mut *mut wasm_extern_t,
}
#[repr(C)]
pub struct wasm_extern_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_memory_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_func_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_module_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_trap_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_instance_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_val_vec_t {
pub size: usize,
pub data: *mut wasm_val_t,
}
#[repr(C)]
pub struct wasm_val_t {
pub kind: wasm_valkind_t,
pub of: wasm_val_t_union,
}
#[repr(C)]
pub union wasm_val_t_union {
pub i32: i32,
pub i64: i64,
pub f32: f32,
pub f64: f64,
pub ref_: *mut wasm_ref_t,
}
#[repr(C)]
pub struct wasm_ref_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_exporttype_vec_t {
pub size: usize,
pub data: *mut *mut wasm_exporttype_t,
}
#[repr(C)]
pub struct wasm_exporttype_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_importtype_vec_t {
pub size: usize,
pub data: *mut *mut wasm_importtype_t,
}
#[repr(C)]
pub struct wasm_importtype_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_functype_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_valtype_vec_t {
pub size: usize,
pub data: *mut *mut wasm_valtype_t,
}
#[repr(C)]
pub struct wasm_valtype_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_store_t {
_unused: [u8; 0],
}
#[repr(C)]
pub struct wasm_engine_t {
_unused: [u8; 0],
}
fn resolve(ptr: &AtomicUsize, name: &str) -> usize {
match ptr.load(SeqCst) {
0 => {}
n => return n,
}
let fnptr = dynamically_resolve(name);
ptr.store(fnptr, SeqCst);
fnptr
}
#[cfg(unix)]
fn dynamically_resolve(name: &str) -> usize {
extern "C" {
fn dlopen(filename: *const u8, flags: i32) -> *mut u8;
fn dlsym(handle: *mut u8, sym: *const u8) -> *mut u8;
}
static HANDLE: AtomicUsize = AtomicUsize::new(0);
unsafe {
let handle = match HANDLE.load(SeqCst) {
0 => {
let path = concat!(env!("WATT_JIT"), "\0");
let handle = dlopen(path.as_ptr(), 1);
assert!(
!handle.is_null(),
"failed to dynamically open: {}",
env!("WATT_JIT")
);
HANDLE.store(handle as usize, SeqCst);
handle
}
n => n as *mut u8,
};
let ret = dlsym(handle, name.as_ptr());
assert!(!ret.is_null());
ret as usize
}
}
#[cfg(windows)]
fn dynamically_resolve(name: &str) -> usize {
extern "system" {
fn LoadLibraryA(name: *const u8) -> *mut u8;
fn GetProcAddress(handle: *mut u8, sym: *const u8) -> *mut u8;
}
static HANDLE: AtomicUsize = AtomicUsize::new(0);
unsafe {
let handle = match HANDLE.load(SeqCst) {
0 => {
let path = concat!(env!("WATT_JIT"), "\0");
let handle = LoadLibraryA(path.as_ptr());
assert!(
!handle.is_null(),
"failed to dynamically open: {}",
env!("WATT_JIT")
);
HANDLE.store(handle as usize, SeqCst);
handle
}
n => n as *mut u8,
};
let ret = GetProcAddress(handle, name.as_ptr());
assert!(!ret.is_null());
ret as usize
}
}
macro_rules! extern_apis {
($(
pub fn $name:ident($($arg:ident: $ty:ty),* $(,)?) $(-> $ret:ty)?;
)*) => ($(
pub unsafe extern "C" fn $name($($arg: $ty),*) $(-> $ret)? {
static PTR: AtomicUsize = AtomicUsize::new(0);
let _fnptr = resolve(&PTR, concat!(stringify!($name), "\0"));
mem::transmute::<
usize,
unsafe extern "C" fn($($ty),*) $( -> $ret)?
>(_fnptr)($($arg),*)
}
)*);
}
extern_apis! {
pub fn wasm_byte_vec_delete(arg1: *mut wasm_byte_vec_t);
pub fn wasm_engine_delete(arg1: *mut wasm_engine_t);
pub fn wasm_engine_new() -> *mut wasm_engine_t;
pub fn wasm_store_delete(arg1: *mut wasm_store_t);
pub fn wasm_store_new(arg1: *mut wasm_engine_t) -> *mut wasm_store_t;
pub fn wasm_valtype_delete(arg1: *mut wasm_valtype_t);
pub fn wasm_valtype_vec_new(
out: *mut wasm_valtype_vec_t,
arg1: usize,
arg2: *const *mut wasm_valtype_t,
);
pub fn wasm_valtype_new(arg1: wasm_valkind_t) -> *mut wasm_valtype_t;
pub fn wasm_functype_delete(arg1: *mut wasm_functype_t);
pub fn wasm_functype_new(
params: *mut wasm_valtype_vec_t,
results: *mut wasm_valtype_vec_t,
) -> *mut wasm_functype_t;
pub fn wasm_importtype_vec_delete(arg1: *mut wasm_importtype_vec_t);
pub fn wasm_importtype_module(arg1: *const wasm_importtype_t) -> *const wasm_name_t;
pub fn wasm_importtype_name(arg1: *const wasm_importtype_t) -> *const wasm_name_t;
pub fn wasm_exporttype_vec_delete(arg1: *mut wasm_exporttype_vec_t);
pub fn wasm_exporttype_name(arg1: *const wasm_exporttype_t) -> *const wasm_name_t;
pub fn wasm_trap_delete(arg1: *mut wasm_trap_t);
pub fn wasm_trap_message(arg1: *const wasm_trap_t, out: *mut wasm_message_t);
pub fn wasm_module_delete(arg1: *mut wasm_module_t);
pub fn wasm_module_new(
arg1: *mut wasm_store_t,
binary: *const wasm_byte_vec_t,
) -> *mut wasm_module_t;
pub fn wasm_module_imports(arg1: *const wasm_module_t, out: *mut wasm_importtype_vec_t);
pub fn wasm_module_exports(arg1: *const wasm_module_t, out: *mut wasm_exporttype_vec_t);
pub fn wasm_func_delete(arg1: *mut wasm_func_t);
pub fn wasm_func_new_with_env(
arg1: *mut wasm_store_t,
type_: *const wasm_functype_t,
arg2: wasm_func_callback_with_env_t,
env: *mut c_void,
finalizer: Option<unsafe extern "C" fn(arg1: *mut c_void)>,
) -> *mut wasm_func_t;
pub fn wasm_func_param_arity(arg1: *const wasm_func_t) -> usize;
pub fn wasm_func_result_arity(arg1: *const wasm_func_t) -> usize;
pub fn wasm_func_call(
arg1: *const wasm_func_t,
args: *const wasm_val_vec_t,
results: *mut wasm_val_vec_t,
) -> *mut wasm_trap_t;
pub fn wasm_memory_data(arg1: *mut wasm_memory_t) -> *mut u8;
pub fn wasm_memory_data_size(arg1: *const wasm_memory_t) -> usize;
pub fn wasm_extern_vec_delete(arg1: *mut wasm_extern_vec_t);
pub fn wasm_extern_kind(arg1: *const wasm_extern_t) -> wasm_externkind_t;
pub fn wasm_func_as_extern(arg1: *mut wasm_func_t) -> *mut wasm_extern_t;
pub fn wasm_extern_as_func(arg1: *mut wasm_extern_t) -> *mut wasm_func_t;
pub fn wasm_extern_as_memory(arg1: *mut wasm_extern_t) -> *mut wasm_memory_t;
pub fn wasm_instance_delete(arg1: *mut wasm_instance_t);
pub fn wasm_instance_new(
arg1: *mut wasm_store_t,
arg2: *const wasm_module_t,
imports: *const wasm_extern_vec_t,
arg3: *mut *mut wasm_trap_t,
) -> *mut wasm_instance_t;
pub fn wasm_instance_exports(arg1: *const wasm_instance_t, out: *mut wasm_extern_vec_t);
}