mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-12 13:28:49 +00:00
feat(c-api) Move all types into their own modules.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
|
use super::super::trap::wasm_trap_t;
|
||||||
|
use super::super::types::{wasm_functype_t, wasm_valkind_enum};
|
||||||
use super::super::value::{wasm_val_inner, wasm_val_t};
|
use super::super::value::{wasm_val_inner, wasm_val_t};
|
||||||
use super::super::{wasm_functype_t, wasm_trap_t, wasm_valkind_enum};
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|||||||
2
lib/c-api/src/wasm_c_api/externals/global.rs
vendored
2
lib/c-api/src/wasm_c_api/externals/global.rs
vendored
@@ -1,6 +1,6 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
|
use super::super::types::wasm_globaltype_t;
|
||||||
use super::super::value::wasm_val_t;
|
use super::super::value::wasm_val_t;
|
||||||
use super::super::wasm_globaltype_t;
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use wasmer::{Global, Store, Val};
|
use wasmer::{Global, Store, Val};
|
||||||
|
|||||||
3
lib/c-api/src/wasm_c_api/externals/memory.rs
vendored
3
lib/c-api/src/wasm_c_api/externals/memory.rs
vendored
@@ -1,6 +1,5 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
use super::super::wasm_memorytype_t;
|
use super::super::types::wasm_memorytype_t;
|
||||||
use crate::c_try;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use wasmer::{Memory, Pages, Store};
|
use wasmer::{Memory, Pages, Store};
|
||||||
|
|||||||
3
lib/c-api/src/wasm_c_api/externals/table.rs
vendored
3
lib/c-api/src/wasm_c_api/externals/table.rs
vendored
@@ -1,6 +1,5 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
use super::super::{wasm_ref_t, wasm_table_size_t, wasm_tabletype_t};
|
use super::super::types::{wasm_ref_t, wasm_table_size_t, wasm_tabletype_t};
|
||||||
use crate::c_try;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use wasmer::{Store, Table};
|
use wasmer::{Store, Table};
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
use super::{
|
use super::externals::{wasm_extern_t, wasm_extern_vec_t};
|
||||||
externals::{wasm_extern_t, wasm_extern_vec_t},
|
use super::module::wasm_module_t;
|
||||||
module::wasm_module_t,
|
use super::store::wasm_store_t;
|
||||||
store::wasm_store_t,
|
use super::trap::wasm_trap_t;
|
||||||
wasm_trap_t,
|
|
||||||
};
|
|
||||||
use crate::c_try;
|
|
||||||
use crate::ordered_resolver::OrderedResolver;
|
use crate::ordered_resolver::OrderedResolver;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|||||||
@@ -155,3 +155,21 @@ macro_rules! wasm_declare_own {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! c_try {
|
||||||
|
($expr:expr) => {{
|
||||||
|
let res: Result<_, _> = $expr;
|
||||||
|
match res {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
crate::error::update_last_error(err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
($expr:expr, $e:expr) => {{
|
||||||
|
let opt: Option<_> = $expr;
|
||||||
|
c_try!(opt.ok_or_else(|| $e))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,905 +8,8 @@ pub mod externals;
|
|||||||
pub mod instance;
|
pub mod instance;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
pub mod store;
|
pub mod store;
|
||||||
pub(crate) mod utils;
|
pub mod trap;
|
||||||
|
pub mod types;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
#[cfg(feature = "wasi")]
|
#[cfg(feature = "wasi")]
|
||||||
pub mod wasi;
|
pub mod wasi;
|
||||||
|
|
||||||
// required due to really weird Rust resolution rules
|
|
||||||
// https://github.com/rust-lang/rust/issues/57966
|
|
||||||
use crate::c_try;
|
|
||||||
use externals::wasm_extern_t;
|
|
||||||
use std::convert::{TryFrom, TryInto};
|
|
||||||
use std::mem;
|
|
||||||
use std::ptr::NonNull;
|
|
||||||
use thiserror::Error;
|
|
||||||
use value::wasm_valkind_t;
|
|
||||||
use wasmer::{
|
|
||||||
ExportType, ExternType, FunctionType, GlobalType, ImportType, MemoryType, Mutability, Pages,
|
|
||||||
RuntimeError, TableType, ValType,
|
|
||||||
};
|
|
||||||
#[cfg(feature = "jit")]
|
|
||||||
use wasmer_engine_jit::JIT;
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub type wasm_table_size_t = u32;
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub type wasm_mutability_t = u8;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(u8)]
|
|
||||||
enum wasm_mutability_enum {
|
|
||||||
WASM_CONST = 0,
|
|
||||||
WASM_VAR,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl wasm_mutability_enum {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn is_mutable(self) -> bool {
|
|
||||||
self == Self::WASM_VAR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<wasm_mutability_t> for wasm_mutability_enum {
|
|
||||||
type Error = &'static str;
|
|
||||||
|
|
||||||
fn try_from(item: wasm_mutability_t) -> Result<Self, Self::Error> {
|
|
||||||
Ok(match item {
|
|
||||||
0 => wasm_mutability_enum::WASM_CONST,
|
|
||||||
1 => wasm_mutability_enum::WASM_VAR,
|
|
||||||
_ => return Err("wasm_mutability_t value out of bounds"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<wasm_mutability_enum> for wasm_mutability_t {
|
|
||||||
fn from(other: wasm_mutability_enum) -> Self {
|
|
||||||
other as wasm_mutability_t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<wasm_mutability_enum> for Mutability {
|
|
||||||
fn from(other: wasm_mutability_enum) -> Self {
|
|
||||||
match other {
|
|
||||||
wasm_mutability_enum::WASM_CONST => Mutability::Const,
|
|
||||||
wasm_mutability_enum::WASM_VAR => Mutability::Var,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Mutability> for wasm_mutability_enum {
|
|
||||||
fn from(other: Mutability) -> Self {
|
|
||||||
match other {
|
|
||||||
Mutability::Const => wasm_mutability_enum::WASM_CONST,
|
|
||||||
Mutability::Var => wasm_mutability_enum::WASM_VAR,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<wasm_valkind_enum> for ValType {
|
|
||||||
fn from(other: wasm_valkind_enum) -> Self {
|
|
||||||
use wasm_valkind_enum::*;
|
|
||||||
match other {
|
|
||||||
WASM_I32 => ValType::I32,
|
|
||||||
WASM_I64 => ValType::I64,
|
|
||||||
WASM_F32 => ValType::F32,
|
|
||||||
WASM_F64 => ValType::F64,
|
|
||||||
WASM_ANYREF => ValType::ExternRef,
|
|
||||||
WASM_FUNCREF => ValType::FuncRef,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<wasm_valtype_t> for ValType {
|
|
||||||
fn from(other: wasm_valtype_t) -> Self {
|
|
||||||
other.valkind.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ValType> for wasm_valtype_t {
|
|
||||||
fn from(other: ValType) -> Self {
|
|
||||||
Self {
|
|
||||||
valkind: other.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum wasm_valkind_enum {
|
|
||||||
WASM_I32 = 0,
|
|
||||||
WASM_I64 = 1,
|
|
||||||
WASM_F32 = 2,
|
|
||||||
WASM_F64 = 3,
|
|
||||||
WASM_ANYREF = 128,
|
|
||||||
WASM_FUNCREF = 129,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ValType> for wasm_valkind_enum {
|
|
||||||
fn from(other: ValType) -> Self {
|
|
||||||
match other {
|
|
||||||
ValType::I32 => Self::WASM_I32,
|
|
||||||
ValType::I64 => Self::WASM_I64,
|
|
||||||
ValType::F32 => Self::WASM_F32,
|
|
||||||
ValType::F64 => Self::WASM_F64,
|
|
||||||
ValType::V128 => todo!("no v128 type in Wasm C API yet!"),
|
|
||||||
ValType::ExternRef => Self::WASM_ANYREF,
|
|
||||||
ValType::FuncRef => Self::WASM_FUNCREF,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub type wasm_byte_t = u8;
|
|
||||||
wasm_declare_vec!(byte);
|
|
||||||
|
|
||||||
// opaque type over `ExternRef`?
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct wasm_ref_t;
|
|
||||||
|
|
||||||
// opaque type which is a `RuntimeError`
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_trap_t {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_trap_delete(trap: Option<NonNull<wasm_trap_t>>) {
|
|
||||||
if let Some(t_inner) = trap {
|
|
||||||
let _ = Box::from_raw(t_inner.cast::<RuntimeError>().as_ptr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_trap_message(
|
|
||||||
trap: *const wasm_trap_t,
|
|
||||||
out_ptr: *mut wasm_byte_vec_t,
|
|
||||||
) {
|
|
||||||
let re = &*(trap as *const RuntimeError);
|
|
||||||
// this code assumes no nul bytes appear in the message
|
|
||||||
let mut message = format!("{}\0", re);
|
|
||||||
message.shrink_to_fit();
|
|
||||||
|
|
||||||
// TODO use `String::into_raw_parts` when it gets stabilized
|
|
||||||
(*out_ptr).size = message.as_bytes().len();
|
|
||||||
(*out_ptr).data = message.as_mut_ptr();
|
|
||||||
mem::forget(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// in trap/RuntimeError we need to store
|
|
||||||
// 1. message
|
|
||||||
// 2. origin (frame); frame contains:
|
|
||||||
// 1. func index
|
|
||||||
// 2. func offset
|
|
||||||
// 3. module offset
|
|
||||||
// 4. which instance this was apart of
|
|
||||||
|
|
||||||
/*#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_trap_trace(trap: *const wasm_trap_t, out_ptr: *mut wasm_frame_vec_t) {
|
|
||||||
let re = &*(trap as *const RuntimeError);
|
|
||||||
todo!()
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_valtype_t {
|
|
||||||
valkind: wasm_valkind_enum,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for wasm_valtype_t {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
valkind: wasm_valkind_enum::WASM_I32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_boxed_vec!(valtype);
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_valtype_new(kind: wasm_valkind_t) -> Option<Box<wasm_valtype_t>> {
|
|
||||||
let kind_enum = kind.try_into().ok()?;
|
|
||||||
let valtype = wasm_valtype_t { valkind: kind_enum };
|
|
||||||
Some(Box::new(valtype))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_valtype_delete(_valtype: Option<Box<wasm_valtype_t>>) {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_valtype_kind(valtype: *const wasm_valtype_t) -> wasm_valkind_t {
|
|
||||||
if valtype.is_null() {
|
|
||||||
// TODO: handle error
|
|
||||||
panic!("wasm_valtype_kind: argument is null pointer");
|
|
||||||
}
|
|
||||||
return (*valtype).valkind as wasm_valkind_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
//wasm_declare_ref!(trap);
|
|
||||||
//wasm_declare_ref!(foreign);
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct wasm_globaltype_t {
|
|
||||||
extern_: wasm_externtype_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl wasm_globaltype_t {
|
|
||||||
fn as_globaltype(&self) -> &GlobalType {
|
|
||||||
if let ExternType::Global(ref g) = self.extern_.inner {
|
|
||||||
g
|
|
||||||
} else {
|
|
||||||
unreachable!(
|
|
||||||
"Data corruption detected: `wasm_globaltype_t` does not contain a `GlobalType`"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_vec!(globaltype);
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_globaltype_new(
|
|
||||||
// own
|
|
||||||
valtype: Option<Box<wasm_valtype_t>>,
|
|
||||||
mutability: wasm_mutability_t,
|
|
||||||
) -> Option<Box<wasm_globaltype_t>> {
|
|
||||||
wasm_globaltype_new_inner(valtype?, mutability)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_globaltype_delete(_globaltype: Option<Box<wasm_globaltype_t>>) {}
|
|
||||||
|
|
||||||
unsafe fn wasm_globaltype_new_inner(
|
|
||||||
// own
|
|
||||||
valtype: Box<wasm_valtype_t>,
|
|
||||||
mutability: wasm_mutability_t,
|
|
||||||
) -> Option<Box<wasm_globaltype_t>> {
|
|
||||||
let me: wasm_mutability_enum = mutability.try_into().ok()?;
|
|
||||||
let gd = Box::new(wasm_globaltype_t {
|
|
||||||
extern_: wasm_externtype_t {
|
|
||||||
inner: ExternType::Global(GlobalType::new((*valtype).into(), me.into())),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
wasm_valtype_delete(Some(valtype));
|
|
||||||
|
|
||||||
Some(gd)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_globaltype_mutability(
|
|
||||||
globaltype: &wasm_globaltype_t,
|
|
||||||
) -> wasm_mutability_t {
|
|
||||||
let gt = globaltype.as_globaltype();
|
|
||||||
wasm_mutability_enum::from(gt.mutability).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix memory leak
|
|
||||||
// this function leaks memory because the returned limits pointer is not owned
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_globaltype_content(
|
|
||||||
globaltype: &wasm_globaltype_t,
|
|
||||||
) -> *const wasm_valtype_t {
|
|
||||||
let gt = globaltype.as_globaltype();
|
|
||||||
Box::into_raw(Box::new(gt.ty.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
#[repr(C)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct wasm_tabletype_t {
|
|
||||||
extern_: wasm_externtype_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_vec!(tabletype);
|
|
||||||
|
|
||||||
impl wasm_tabletype_t {
|
|
||||||
fn as_tabletype(&self) -> &TableType {
|
|
||||||
if let ExternType::Table(ref t) = self.extern_.inner {
|
|
||||||
t
|
|
||||||
} else {
|
|
||||||
unreachable!(
|
|
||||||
"Data corruption detected: `wasm_tabletype_t` does not contain a `TableType`"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_tabletype_new(
|
|
||||||
// own
|
|
||||||
valtype: Box<wasm_valtype_t>,
|
|
||||||
limits: &wasm_limits_t,
|
|
||||||
) -> Box<wasm_tabletype_t> {
|
|
||||||
// TODO: investigate if `0` is in fact a sentinel value here
|
|
||||||
let max_elements = if limits.max == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(limits.max as _)
|
|
||||||
};
|
|
||||||
let out = Box::new(wasm_tabletype_t {
|
|
||||||
extern_: wasm_externtype_t {
|
|
||||||
inner: ExternType::Table(TableType::new(
|
|
||||||
(*valtype).into(),
|
|
||||||
limits.min as _,
|
|
||||||
max_elements,
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
wasm_valtype_delete(Some(valtype));
|
|
||||||
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix memory leak
|
|
||||||
// this function leaks memory because the returned limits pointer is not owned
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_tabletype_limits(
|
|
||||||
tabletype: &wasm_tabletype_t,
|
|
||||||
) -> *const wasm_limits_t {
|
|
||||||
let tt = tabletype.as_tabletype();
|
|
||||||
Box::into_raw(Box::new(wasm_limits_t {
|
|
||||||
min: tt.minimum as _,
|
|
||||||
max: tt.maximum.unwrap_or(0),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix memory leak
|
|
||||||
// this function leaks memory because the returned limits pointer is not owned
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_tabletype_element(
|
|
||||||
tabletype: &wasm_tabletype_t,
|
|
||||||
) -> *const wasm_valtype_t {
|
|
||||||
let tt = tabletype.as_tabletype();
|
|
||||||
|
|
||||||
Box::into_raw(Box::new(tt.ty.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_tabletype_delete(_tabletype: Option<Box<wasm_tabletype_t>>) {}
|
|
||||||
|
|
||||||
// opaque type wrapping `MemoryType`
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct wasm_memorytype_t {
|
|
||||||
extern_: wasm_externtype_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl wasm_memorytype_t {
|
|
||||||
pub(crate) fn as_memorytype(&self) -> &MemoryType {
|
|
||||||
if let ExternType::Memory(ref mt) = self.extern_.inner {
|
|
||||||
mt
|
|
||||||
} else {
|
|
||||||
unreachable!(
|
|
||||||
"Data corruption detected: `wasm_memorytype_t` does not contain a `MemoryType`"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_vec!(memorytype);
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_limits_t {
|
|
||||||
min: u32,
|
|
||||||
max: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
|
||||||
let min_pages = Pages(limits.min as _);
|
|
||||||
// TODO: investigate if `0` is in fact a sentinel value here
|
|
||||||
let max_pages = if limits.max == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Pages(limits.max as _))
|
|
||||||
};
|
|
||||||
Box::new(wasm_memorytype_t {
|
|
||||||
extern_: wasm_externtype_t {
|
|
||||||
inner: ExternType::Memory(MemoryType::new(min_pages, max_pages, false)),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_memorytype_delete(_memorytype: Option<Box<wasm_memorytype_t>>) {}
|
|
||||||
|
|
||||||
// TODO: fix memory leak
|
|
||||||
// this function leaks memory because the returned limits pointer is not owned
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_memorytype_limits(mt: &wasm_memorytype_t) -> *const wasm_limits_t {
|
|
||||||
let md = mt.as_memorytype();
|
|
||||||
Box::into_raw(Box::new(wasm_limits_t {
|
|
||||||
min: md.minimum.bytes().0 as _,
|
|
||||||
max: md.maximum.map(|max| max.bytes().0 as _).unwrap_or(0),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct wasm_functype_t {
|
|
||||||
extern_: wasm_externtype_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl wasm_functype_t {
|
|
||||||
pub(crate) fn sig(&self) -> &FunctionType {
|
|
||||||
if let ExternType::Function(ref f) = self.extern_.inner {
|
|
||||||
f
|
|
||||||
} else {
|
|
||||||
unreachable!("data corruption: `wasm_functype_t` does not contain a function")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_vec!(functype);
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_new(
|
|
||||||
// own
|
|
||||||
params: Option<NonNull<wasm_valtype_vec_t>>,
|
|
||||||
// own
|
|
||||||
results: Option<NonNull<wasm_valtype_vec_t>>,
|
|
||||||
) -> Option<Box<wasm_functype_t>> {
|
|
||||||
wasm_functype_new_inner(params?, results?)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn wasm_functype_new_inner(
|
|
||||||
// own
|
|
||||||
params: NonNull<wasm_valtype_vec_t>,
|
|
||||||
// own
|
|
||||||
results: NonNull<wasm_valtype_vec_t>,
|
|
||||||
) -> Option<Box<wasm_functype_t>> {
|
|
||||||
let params = params.as_ref();
|
|
||||||
let results = results.as_ref();
|
|
||||||
let params: Vec<ValType> = params
|
|
||||||
.into_slice()?
|
|
||||||
.iter()
|
|
||||||
.map(|&ptr| *ptr)
|
|
||||||
.map(Into::into)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let results: Vec<ValType> = results
|
|
||||||
.into_slice()?
|
|
||||||
.iter()
|
|
||||||
.map(|&ptr| *ptr)
|
|
||||||
.map(Into::into)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let extern_ = wasm_externtype_t {
|
|
||||||
inner: ExternType::Function(FunctionType::new(params, results)),
|
|
||||||
};
|
|
||||||
Some(Box::new(wasm_functype_t { extern_ }))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_delete(_ft: Option<Box<wasm_functype_t>>) {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_copy(
|
|
||||||
arg: Option<NonNull<wasm_functype_t>>,
|
|
||||||
) -> Option<Box<wasm_functype_t>> {
|
|
||||||
let arg = arg?;
|
|
||||||
let funcsig = arg.as_ref();
|
|
||||||
Some(Box::new(funcsig.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix memory leak
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_params(ft: &wasm_functype_t) -> *const wasm_valtype_vec_t {
|
|
||||||
let mut valtypes = ft
|
|
||||||
.sig()
|
|
||||||
.params()
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(Into::into)
|
|
||||||
.map(Box::new)
|
|
||||||
.map(Box::into_raw)
|
|
||||||
.collect::<Vec<*mut wasm_valtype_t>>();
|
|
||||||
let out = Box::into_raw(Box::new(wasm_valtype_vec_t {
|
|
||||||
size: valtypes.len(),
|
|
||||||
data: valtypes.as_mut_ptr(),
|
|
||||||
}));
|
|
||||||
mem::forget(valtypes);
|
|
||||||
out as *const _
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix memory leak
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_results(ft: &wasm_functype_t) -> *const wasm_valtype_vec_t {
|
|
||||||
let mut valtypes = ft
|
|
||||||
.sig()
|
|
||||||
.results()
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(Into::into)
|
|
||||||
.map(Box::new)
|
|
||||||
.map(Box::into_raw)
|
|
||||||
.collect::<Vec<*mut wasm_valtype_t>>();
|
|
||||||
let out = Box::into_raw(Box::new(wasm_valtype_vec_t {
|
|
||||||
size: valtypes.len(),
|
|
||||||
data: valtypes.as_mut_ptr(),
|
|
||||||
}));
|
|
||||||
mem::forget(valtypes);
|
|
||||||
out as *const _
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_frame_t {}
|
|
||||||
|
|
||||||
wasm_declare_vec!(frame);
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct wasm_externtype_t {
|
|
||||||
inner: ExternType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
|
|
||||||
Box::new(wasm_externtype_t {
|
|
||||||
inner: e.inner.ty(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_delete(_et: Option<Box<wasm_externtype_t>>) {}
|
|
||||||
|
|
||||||
impl From<ExternType> for wasm_externtype_t {
|
|
||||||
fn from(other: ExternType) -> Self {
|
|
||||||
Self { inner: other }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&ExternType> for wasm_externtype_t {
|
|
||||||
fn from(other: &ExternType) -> Self {
|
|
||||||
other.clone().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type wasm_externkind_t = u8;
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum wasm_externkind_enum {
|
|
||||||
WASM_EXTERN_FUNC = 0,
|
|
||||||
WASM_EXTERN_GLOBAL = 1,
|
|
||||||
WASM_EXTERN_TABLE = 2,
|
|
||||||
WASM_EXTERN_MEMORY = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
|
|
||||||
wasm_externkind_enum::from(e.inner.ty()) as wasm_externkind_t
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ExternType> for wasm_externkind_enum {
|
|
||||||
fn from(other: ExternType) -> Self {
|
|
||||||
(&other).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<&ExternType> for wasm_externkind_enum {
|
|
||||||
fn from(other: &ExternType) -> Self {
|
|
||||||
match other {
|
|
||||||
ExternType::Function(_) => Self::WASM_EXTERN_FUNC,
|
|
||||||
ExternType::Global(_) => Self::WASM_EXTERN_GLOBAL,
|
|
||||||
ExternType::Table(_) => Self::WASM_EXTERN_TABLE,
|
|
||||||
ExternType::Memory(_) => Self::WASM_EXTERN_MEMORY,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_kind(et: &wasm_externtype_t) -> wasm_externkind_t {
|
|
||||||
wasm_externkind_enum::from(&et.inner) as wasm_externkind_t
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Error)]
|
|
||||||
#[error("failed to convert from `wasm_externtype_t`: {0}")]
|
|
||||||
pub struct ExternTypeConversionError(&'static str);
|
|
||||||
impl From<&'static str> for ExternTypeConversionError {
|
|
||||||
fn from(other: &'static str) -> Self {
|
|
||||||
Self(other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_functype_t {
|
|
||||||
type Error = ExternTypeConversionError;
|
|
||||||
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
|
||||||
if let ExternType::Function(_) = other.inner {
|
|
||||||
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
|
||||||
} else {
|
|
||||||
Err(ExternTypeConversionError("Wrong type: expected function"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_globaltype_t {
|
|
||||||
type Error = ExternTypeConversionError;
|
|
||||||
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
|
||||||
if let ExternType::Global(_) = other.inner {
|
|
||||||
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
|
||||||
} else {
|
|
||||||
Err(ExternTypeConversionError("Wrong type: expected global"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_memorytype_t {
|
|
||||||
type Error = ExternTypeConversionError;
|
|
||||||
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
|
||||||
if let ExternType::Memory(_) = other.inner {
|
|
||||||
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
|
||||||
} else {
|
|
||||||
Err(ExternTypeConversionError("Wrong type: expected memory"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_tabletype_t {
|
|
||||||
type Error = ExternTypeConversionError;
|
|
||||||
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
|
||||||
if let ExternType::Table(_) = other.inner {
|
|
||||||
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
|
||||||
} else {
|
|
||||||
Err(ExternTypeConversionError("Wrong type: expected table"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_functype_const(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_functype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_functype(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_functype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_as_externtype_const(
|
|
||||||
ft: &'static wasm_functype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
&ft.extern_
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_functype_as_externtype(
|
|
||||||
ft: &'static wasm_functype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
&ft.extern_
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_memorytype_const(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_memorytype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_memorytype(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_memorytype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_memorytype_as_externtype_const(
|
|
||||||
mt: &'static wasm_memorytype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
&mt.extern_
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_memorytype_as_externtype(
|
|
||||||
mt: &'static wasm_memorytype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
&mt.extern_
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_globaltype_const(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_globaltype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_globaltype(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_globaltype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_globaltype_as_externtype_const(
|
|
||||||
gt: &'static wasm_globaltype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
>.extern_
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_globaltype_as_externtype(
|
|
||||||
gt: &'static wasm_globaltype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
>.extern_
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_tabletype_const(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_tabletype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_externtype_as_tabletype(
|
|
||||||
et: &'static wasm_externtype_t,
|
|
||||||
) -> Option<&'static wasm_tabletype_t> {
|
|
||||||
Some(c_try!(et.try_into()))
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_tabletype_as_externtype_const(
|
|
||||||
tt: &'static wasm_tabletype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
&tt.extern_
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_tabletype_as_externtype(
|
|
||||||
tt: &'static wasm_tabletype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
&tt.extern_
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type wasm_name_t = wasm_byte_vec_t;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct wasm_exporttype_t {
|
|
||||||
name: NonNull<wasm_name_t>,
|
|
||||||
extern_type: NonNull<wasm_externtype_t>,
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_boxed_vec!(exporttype);
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_exporttype_new(
|
|
||||||
name: NonNull<wasm_name_t>,
|
|
||||||
extern_type: NonNull<wasm_externtype_t>,
|
|
||||||
) -> Box<wasm_exporttype_t> {
|
|
||||||
Box::new(wasm_exporttype_t { name, extern_type })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_exporttype_name(et: &'static wasm_exporttype_t) -> &'static wasm_name_t {
|
|
||||||
unsafe { et.name.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_exporttype_type(
|
|
||||||
et: &'static wasm_exporttype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
unsafe { et.extern_type.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ExportType> for wasm_exporttype_t {
|
|
||||||
fn from(other: ExportType) -> Self {
|
|
||||||
(&other).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&ExportType> for wasm_exporttype_t {
|
|
||||||
fn from(other: &ExportType) -> Self {
|
|
||||||
// TODO: double check that freeing String as `Vec<u8>` is valid
|
|
||||||
let name = {
|
|
||||||
let mut heap_str: Box<str> = other.name().to_string().into_boxed_str();
|
|
||||||
let char_ptr = heap_str.as_mut_ptr();
|
|
||||||
let str_len = heap_str.bytes().len();
|
|
||||||
let name_inner = wasm_name_t {
|
|
||||||
size: str_len,
|
|
||||||
data: char_ptr,
|
|
||||||
};
|
|
||||||
Box::leak(heap_str);
|
|
||||||
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(name_inner))) }
|
|
||||||
};
|
|
||||||
|
|
||||||
let extern_type = {
|
|
||||||
let extern_type: wasm_externtype_t = other.ty().into();
|
|
||||||
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(extern_type))) }
|
|
||||||
};
|
|
||||||
|
|
||||||
wasm_exporttype_t { name, extern_type }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: improve ownership in `importtype_t` (can we safely use `Box<wasm_name_t>` here?)
|
|
||||||
#[repr(C)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct wasm_importtype_t {
|
|
||||||
module: NonNull<wasm_name_t>,
|
|
||||||
name: NonNull<wasm_name_t>,
|
|
||||||
extern_type: NonNull<wasm_externtype_t>,
|
|
||||||
}
|
|
||||||
|
|
||||||
wasm_declare_boxed_vec!(importtype);
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_importtype_new(
|
|
||||||
module: NonNull<wasm_name_t>,
|
|
||||||
name: NonNull<wasm_name_t>,
|
|
||||||
extern_type: NonNull<wasm_externtype_t>,
|
|
||||||
) -> Box<wasm_importtype_t> {
|
|
||||||
Box::new(wasm_importtype_t {
|
|
||||||
name,
|
|
||||||
module,
|
|
||||||
extern_type,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_importtype_module(et: &'static wasm_importtype_t) -> &'static wasm_name_t {
|
|
||||||
unsafe { et.module.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_importtype_name(et: &'static wasm_importtype_t) -> &'static wasm_name_t {
|
|
||||||
unsafe { et.name.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wasm_importtype_type(
|
|
||||||
et: &'static wasm_importtype_t,
|
|
||||||
) -> &'static wasm_externtype_t {
|
|
||||||
unsafe { et.extern_type.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_importtype_delete(_importtype: Option<Box<wasm_importtype_t>>) {}
|
|
||||||
|
|
||||||
impl From<ImportType> for wasm_importtype_t {
|
|
||||||
fn from(other: ImportType) -> Self {
|
|
||||||
(&other).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&ImportType> for wasm_importtype_t {
|
|
||||||
fn from(other: &ImportType) -> Self {
|
|
||||||
// TODO: double check that freeing String as `Vec<u8>` is valid
|
|
||||||
let name = {
|
|
||||||
let mut heap_str: Box<str> = other.name().to_string().into_boxed_str();
|
|
||||||
let char_ptr = heap_str.as_mut_ptr();
|
|
||||||
let str_len = heap_str.bytes().len();
|
|
||||||
let name_inner = wasm_name_t {
|
|
||||||
size: str_len,
|
|
||||||
data: char_ptr,
|
|
||||||
};
|
|
||||||
Box::leak(heap_str);
|
|
||||||
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(name_inner))) }
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: double check that freeing String as `Vec<u8>` is valid
|
|
||||||
let module = {
|
|
||||||
let mut heap_str: Box<str> = other.module().to_string().into_boxed_str();
|
|
||||||
let char_ptr = heap_str.as_mut_ptr();
|
|
||||||
let str_len = heap_str.bytes().len();
|
|
||||||
let name_inner = wasm_name_t {
|
|
||||||
size: str_len,
|
|
||||||
data: char_ptr,
|
|
||||||
};
|
|
||||||
Box::leak(heap_str);
|
|
||||||
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(name_inner))) }
|
|
||||||
};
|
|
||||||
|
|
||||||
let extern_type = {
|
|
||||||
let extern_type: wasm_externtype_t = other.ty().into();
|
|
||||||
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(extern_type))) }
|
|
||||||
};
|
|
||||||
|
|
||||||
wasm_importtype_t {
|
|
||||||
name,
|
|
||||||
module,
|
|
||||||
extern_type,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use super::store::wasm_store_t;
|
use super::store::wasm_store_t;
|
||||||
use super::{
|
use super::types::{
|
||||||
wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t,
|
wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t,
|
||||||
wasm_importtype_vec_t,
|
wasm_importtype_vec_t,
|
||||||
};
|
};
|
||||||
use crate::c_try;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|||||||
48
lib/c-api/src/wasm_c_api/trap.rs
Normal file
48
lib/c-api/src/wasm_c_api/trap.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
use super::types::wasm_byte_vec_t;
|
||||||
|
use std::mem;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use wasmer::RuntimeError;
|
||||||
|
|
||||||
|
// opaque type which is a `RuntimeError`
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_trap_t {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_trap_delete(trap: Option<NonNull<wasm_trap_t>>) {
|
||||||
|
if let Some(t_inner) = trap {
|
||||||
|
let _ = Box::from_raw(t_inner.cast::<RuntimeError>().as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_trap_message(
|
||||||
|
trap: *const wasm_trap_t,
|
||||||
|
out_ptr: *mut wasm_byte_vec_t,
|
||||||
|
) {
|
||||||
|
let re = &*(trap as *const RuntimeError);
|
||||||
|
// this code assumes no nul bytes appear in the message
|
||||||
|
let mut message = format!("{}\0", re);
|
||||||
|
message.shrink_to_fit();
|
||||||
|
|
||||||
|
// TODO use `String::into_raw_parts` when it gets stabilized
|
||||||
|
(*out_ptr).size = message.as_bytes().len();
|
||||||
|
(*out_ptr).data = message.as_mut_ptr();
|
||||||
|
mem::forget(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// in trap/RuntimeError we need to store
|
||||||
|
// 1. message
|
||||||
|
// 2. origin (frame); frame contains:
|
||||||
|
// 1. func index
|
||||||
|
// 2. func offset
|
||||||
|
// 3. module offset
|
||||||
|
// 4. which instance this was apart of
|
||||||
|
|
||||||
|
/*#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_trap_trace(trap: *const wasm_trap_t, out_ptr: *mut wasm_frame_vec_t) {
|
||||||
|
let re = &*(trap as *const RuntimeError);
|
||||||
|
todo!()
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//wasm_declare_ref!(trap);
|
||||||
|
//wasm_declare_ref!(foreign);
|
||||||
4
lib/c-api/src/wasm_c_api/types/byte.rs
Normal file
4
lib/c-api/src/wasm_c_api/types/byte.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub type wasm_byte_t = u8;
|
||||||
|
|
||||||
|
wasm_declare_vec!(byte);
|
||||||
62
lib/c-api/src/wasm_c_api/types/export.rs
Normal file
62
lib/c-api/src/wasm_c_api/types/export.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
use super::{wasm_externtype_t, wasm_name_t};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use wasmer::ExportType;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct wasm_exporttype_t {
|
||||||
|
name: NonNull<wasm_name_t>,
|
||||||
|
extern_type: NonNull<wasm_externtype_t>,
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_boxed_vec!(exporttype);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_exporttype_new(
|
||||||
|
name: NonNull<wasm_name_t>,
|
||||||
|
extern_type: NonNull<wasm_externtype_t>,
|
||||||
|
) -> Box<wasm_exporttype_t> {
|
||||||
|
Box::new(wasm_exporttype_t { name, extern_type })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_exporttype_name(et: &'static wasm_exporttype_t) -> &'static wasm_name_t {
|
||||||
|
unsafe { et.name.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_exporttype_type(
|
||||||
|
et: &'static wasm_exporttype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
unsafe { et.extern_type.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ExportType> for wasm_exporttype_t {
|
||||||
|
fn from(other: ExportType) -> Self {
|
||||||
|
(&other).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ExportType> for wasm_exporttype_t {
|
||||||
|
fn from(other: &ExportType) -> Self {
|
||||||
|
// TODO: double check that freeing String as `Vec<u8>` is valid
|
||||||
|
let name = {
|
||||||
|
let mut heap_str: Box<str> = other.name().to_string().into_boxed_str();
|
||||||
|
let char_ptr = heap_str.as_mut_ptr();
|
||||||
|
let str_len = heap_str.bytes().len();
|
||||||
|
let name_inner = wasm_name_t {
|
||||||
|
size: str_len,
|
||||||
|
data: char_ptr,
|
||||||
|
};
|
||||||
|
Box::leak(heap_str);
|
||||||
|
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(name_inner))) }
|
||||||
|
};
|
||||||
|
|
||||||
|
let extern_type = {
|
||||||
|
let extern_type: wasm_externtype_t = other.ty().into();
|
||||||
|
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(extern_type))) }
|
||||||
|
};
|
||||||
|
|
||||||
|
wasm_exporttype_t { name, extern_type }
|
||||||
|
}
|
||||||
|
}
|
||||||
243
lib/c-api/src/wasm_c_api/types/extern_.rs
Normal file
243
lib/c-api/src/wasm_c_api/types/extern_.rs
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
use super::super::externals::wasm_extern_t;
|
||||||
|
use super::{wasm_functype_t, wasm_globaltype_t, wasm_memorytype_t, wasm_tabletype_t};
|
||||||
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
use std::mem;
|
||||||
|
use thiserror::Error;
|
||||||
|
use wasmer::ExternType;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct wasm_externtype_t {
|
||||||
|
pub(crate) inner: ExternType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
|
||||||
|
Box::new(wasm_externtype_t {
|
||||||
|
inner: e.inner.ty(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_delete(_et: Option<Box<wasm_externtype_t>>) {}
|
||||||
|
|
||||||
|
impl From<ExternType> for wasm_externtype_t {
|
||||||
|
fn from(other: ExternType) -> Self {
|
||||||
|
Self { inner: other }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ExternType> for wasm_externtype_t {
|
||||||
|
fn from(other: &ExternType) -> Self {
|
||||||
|
other.clone().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type wasm_externkind_t = u8;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum wasm_externkind_enum {
|
||||||
|
WASM_EXTERN_FUNC = 0,
|
||||||
|
WASM_EXTERN_GLOBAL = 1,
|
||||||
|
WASM_EXTERN_TABLE = 2,
|
||||||
|
WASM_EXTERN_MEMORY = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
|
||||||
|
wasm_externkind_enum::from(e.inner.ty()) as wasm_externkind_t
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ExternType> for wasm_externkind_enum {
|
||||||
|
fn from(other: ExternType) -> Self {
|
||||||
|
(&other).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<&ExternType> for wasm_externkind_enum {
|
||||||
|
fn from(other: &ExternType) -> Self {
|
||||||
|
match other {
|
||||||
|
ExternType::Function(_) => Self::WASM_EXTERN_FUNC,
|
||||||
|
ExternType::Global(_) => Self::WASM_EXTERN_GLOBAL,
|
||||||
|
ExternType::Table(_) => Self::WASM_EXTERN_TABLE,
|
||||||
|
ExternType::Memory(_) => Self::WASM_EXTERN_MEMORY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_kind(et: &wasm_externtype_t) -> wasm_externkind_t {
|
||||||
|
wasm_externkind_enum::from(&et.inner) as wasm_externkind_t
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Error)]
|
||||||
|
#[error("failed to convert from `wasm_externtype_t`: {0}")]
|
||||||
|
pub struct ExternTypeConversionError(&'static str);
|
||||||
|
|
||||||
|
impl From<&'static str> for ExternTypeConversionError {
|
||||||
|
fn from(other: &'static str) -> Self {
|
||||||
|
Self(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_functype_t {
|
||||||
|
type Error = ExternTypeConversionError;
|
||||||
|
|
||||||
|
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
||||||
|
if let ExternType::Function(_) = other.inner {
|
||||||
|
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
||||||
|
} else {
|
||||||
|
Err(ExternTypeConversionError("Wrong type: expected function"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_globaltype_t {
|
||||||
|
type Error = ExternTypeConversionError;
|
||||||
|
|
||||||
|
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
||||||
|
if let ExternType::Global(_) = other.inner {
|
||||||
|
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
||||||
|
} else {
|
||||||
|
Err(ExternTypeConversionError("Wrong type: expected global"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_memorytype_t {
|
||||||
|
type Error = ExternTypeConversionError;
|
||||||
|
|
||||||
|
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
||||||
|
if let ExternType::Memory(_) = other.inner {
|
||||||
|
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
||||||
|
} else {
|
||||||
|
Err(ExternTypeConversionError("Wrong type: expected memory"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&'static wasm_externtype_t> for &'static wasm_tabletype_t {
|
||||||
|
type Error = ExternTypeConversionError;
|
||||||
|
|
||||||
|
fn try_from(other: &'static wasm_externtype_t) -> Result<Self, Self::Error> {
|
||||||
|
if let ExternType::Table(_) = other.inner {
|
||||||
|
Ok(unsafe { mem::transmute::<&'static wasm_externtype_t, Self>(other) })
|
||||||
|
} else {
|
||||||
|
Err(ExternTypeConversionError("Wrong type: expected table"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_functype_const(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_functype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_functype(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_functype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_as_externtype_const(
|
||||||
|
ft: &'static wasm_functype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
&ft.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_as_externtype(
|
||||||
|
ft: &'static wasm_functype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
&ft.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_memorytype_const(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_memorytype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_memorytype(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_memorytype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_memorytype_as_externtype_const(
|
||||||
|
mt: &'static wasm_memorytype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
&mt.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_memorytype_as_externtype(
|
||||||
|
mt: &'static wasm_memorytype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
&mt.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_globaltype_const(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_globaltype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_globaltype(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_globaltype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_globaltype_as_externtype_const(
|
||||||
|
gt: &'static wasm_globaltype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
>.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_globaltype_as_externtype(
|
||||||
|
gt: &'static wasm_globaltype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
>.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_tabletype_const(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_tabletype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_externtype_as_tabletype(
|
||||||
|
et: &'static wasm_externtype_t,
|
||||||
|
) -> Option<&'static wasm_tabletype_t> {
|
||||||
|
Some(c_try!(et.try_into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_as_externtype_const(
|
||||||
|
tt: &'static wasm_tabletype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
&tt.extern_
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_as_externtype(
|
||||||
|
tt: &'static wasm_tabletype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
&tt.extern_
|
||||||
|
}
|
||||||
5
lib/c-api/src/wasm_c_api/types/frame.rs
Normal file
5
lib/c-api/src/wasm_c_api/types/frame.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_frame_t {}
|
||||||
|
|
||||||
|
wasm_declare_vec!(frame);
|
||||||
112
lib/c-api/src/wasm_c_api/types/function.rs
Normal file
112
lib/c-api/src/wasm_c_api/types/function.rs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
use super::{wasm_externtype_t, wasm_valtype_t, wasm_valtype_vec_t};
|
||||||
|
use std::mem;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use wasmer::{ExternType, FunctionType, ValType};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct wasm_functype_t {
|
||||||
|
pub(crate) extern_: wasm_externtype_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_functype_t {
|
||||||
|
pub(crate) fn sig(&self) -> &FunctionType {
|
||||||
|
if let ExternType::Function(ref f) = self.extern_.inner {
|
||||||
|
f
|
||||||
|
} else {
|
||||||
|
unreachable!("data corruption: `wasm_functype_t` does not contain a function")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_vec!(functype);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_new(
|
||||||
|
// own
|
||||||
|
params: Option<NonNull<wasm_valtype_vec_t>>,
|
||||||
|
// own
|
||||||
|
results: Option<NonNull<wasm_valtype_vec_t>>,
|
||||||
|
) -> Option<Box<wasm_functype_t>> {
|
||||||
|
wasm_functype_new_inner(params?, results?)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn wasm_functype_new_inner(
|
||||||
|
// own
|
||||||
|
params: NonNull<wasm_valtype_vec_t>,
|
||||||
|
// own
|
||||||
|
results: NonNull<wasm_valtype_vec_t>,
|
||||||
|
) -> Option<Box<wasm_functype_t>> {
|
||||||
|
let params = params.as_ref();
|
||||||
|
let results = results.as_ref();
|
||||||
|
let params: Vec<ValType> = params
|
||||||
|
.into_slice()?
|
||||||
|
.iter()
|
||||||
|
.map(|&ptr| *ptr)
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let results: Vec<ValType> = results
|
||||||
|
.into_slice()?
|
||||||
|
.iter()
|
||||||
|
.map(|&ptr| *ptr)
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let extern_ = wasm_externtype_t {
|
||||||
|
inner: ExternType::Function(FunctionType::new(params, results)),
|
||||||
|
};
|
||||||
|
Some(Box::new(wasm_functype_t { extern_ }))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_delete(_ft: Option<Box<wasm_functype_t>>) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_copy(
|
||||||
|
arg: Option<NonNull<wasm_functype_t>>,
|
||||||
|
) -> Option<Box<wasm_functype_t>> {
|
||||||
|
let arg = arg?;
|
||||||
|
let funcsig = arg.as_ref();
|
||||||
|
Some(Box::new(funcsig.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix memory leak
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_params(ft: &wasm_functype_t) -> *const wasm_valtype_vec_t {
|
||||||
|
let mut valtypes = ft
|
||||||
|
.sig()
|
||||||
|
.params()
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(Into::into)
|
||||||
|
.map(Box::new)
|
||||||
|
.map(Box::into_raw)
|
||||||
|
.collect::<Vec<*mut wasm_valtype_t>>();
|
||||||
|
let out = Box::into_raw(Box::new(wasm_valtype_vec_t {
|
||||||
|
size: valtypes.len(),
|
||||||
|
data: valtypes.as_mut_ptr(),
|
||||||
|
}));
|
||||||
|
mem::forget(valtypes);
|
||||||
|
out as *const _
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix memory leak
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_functype_results(ft: &wasm_functype_t) -> *const wasm_valtype_vec_t {
|
||||||
|
let mut valtypes = ft
|
||||||
|
.sig()
|
||||||
|
.results()
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(Into::into)
|
||||||
|
.map(Box::new)
|
||||||
|
.map(Box::into_raw)
|
||||||
|
.collect::<Vec<*mut wasm_valtype_t>>();
|
||||||
|
let out = Box::into_raw(Box::new(wasm_valtype_vec_t {
|
||||||
|
size: valtypes.len(),
|
||||||
|
data: valtypes.as_mut_ptr(),
|
||||||
|
}));
|
||||||
|
mem::forget(valtypes);
|
||||||
|
out as *const _
|
||||||
|
}
|
||||||
72
lib/c-api/src/wasm_c_api/types/global.rs
Normal file
72
lib/c-api/src/wasm_c_api/types/global.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
use super::{
|
||||||
|
wasm_externtype_t, wasm_mutability_enum, wasm_mutability_t, wasm_valtype_delete, wasm_valtype_t,
|
||||||
|
};
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use wasmer::{ExternType, GlobalType};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct wasm_globaltype_t {
|
||||||
|
pub(crate) extern_: wasm_externtype_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_globaltype_t {
|
||||||
|
pub(crate) fn as_globaltype(&self) -> &GlobalType {
|
||||||
|
if let ExternType::Global(ref g) = self.extern_.inner {
|
||||||
|
g
|
||||||
|
} else {
|
||||||
|
unreachable!(
|
||||||
|
"Data corruption detected: `wasm_globaltype_t` does not contain a `GlobalType`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_vec!(globaltype);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_globaltype_new(
|
||||||
|
// own
|
||||||
|
valtype: Option<Box<wasm_valtype_t>>,
|
||||||
|
mutability: wasm_mutability_t,
|
||||||
|
) -> Option<Box<wasm_globaltype_t>> {
|
||||||
|
wasm_globaltype_new_inner(valtype?, mutability)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_globaltype_delete(_globaltype: Option<Box<wasm_globaltype_t>>) {}
|
||||||
|
|
||||||
|
unsafe fn wasm_globaltype_new_inner(
|
||||||
|
// own
|
||||||
|
valtype: Box<wasm_valtype_t>,
|
||||||
|
mutability: wasm_mutability_t,
|
||||||
|
) -> Option<Box<wasm_globaltype_t>> {
|
||||||
|
let me: wasm_mutability_enum = mutability.try_into().ok()?;
|
||||||
|
let gd = Box::new(wasm_globaltype_t {
|
||||||
|
extern_: wasm_externtype_t {
|
||||||
|
inner: ExternType::Global(GlobalType::new((*valtype).into(), me.into())),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wasm_valtype_delete(Some(valtype));
|
||||||
|
|
||||||
|
Some(gd)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_globaltype_mutability(
|
||||||
|
globaltype: &wasm_globaltype_t,
|
||||||
|
) -> wasm_mutability_t {
|
||||||
|
let gt = globaltype.as_globaltype();
|
||||||
|
wasm_mutability_enum::from(gt.mutability).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix memory leak
|
||||||
|
// this function leaks memory because the returned limits pointer is not owned
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_globaltype_content(
|
||||||
|
globaltype: &wasm_globaltype_t,
|
||||||
|
) -> *const wasm_valtype_t {
|
||||||
|
let gt = globaltype.as_globaltype();
|
||||||
|
Box::into_raw(Box::new(gt.ty.into()))
|
||||||
|
}
|
||||||
94
lib/c-api/src/wasm_c_api/types/import.rs
Normal file
94
lib/c-api/src/wasm_c_api/types/import.rs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
use super::{wasm_externtype_t, wasm_name_t};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use wasmer::ImportType;
|
||||||
|
|
||||||
|
// TODO: improve ownership in `importtype_t` (can we safely use `Box<wasm_name_t>` here?)
|
||||||
|
#[repr(C)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct wasm_importtype_t {
|
||||||
|
pub(crate) module: NonNull<wasm_name_t>,
|
||||||
|
pub(crate) name: NonNull<wasm_name_t>,
|
||||||
|
pub(crate) extern_type: NonNull<wasm_externtype_t>,
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_boxed_vec!(importtype);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_importtype_new(
|
||||||
|
module: NonNull<wasm_name_t>,
|
||||||
|
name: NonNull<wasm_name_t>,
|
||||||
|
extern_type: NonNull<wasm_externtype_t>,
|
||||||
|
) -> Box<wasm_importtype_t> {
|
||||||
|
Box::new(wasm_importtype_t {
|
||||||
|
name,
|
||||||
|
module,
|
||||||
|
extern_type,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_importtype_module(et: &'static wasm_importtype_t) -> &'static wasm_name_t {
|
||||||
|
unsafe { et.module.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_importtype_name(et: &'static wasm_importtype_t) -> &'static wasm_name_t {
|
||||||
|
unsafe { et.name.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_importtype_type(
|
||||||
|
et: &'static wasm_importtype_t,
|
||||||
|
) -> &'static wasm_externtype_t {
|
||||||
|
unsafe { et.extern_type.as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_importtype_delete(_importtype: Option<Box<wasm_importtype_t>>) {}
|
||||||
|
|
||||||
|
impl From<ImportType> for wasm_importtype_t {
|
||||||
|
fn from(other: ImportType) -> Self {
|
||||||
|
(&other).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ImportType> for wasm_importtype_t {
|
||||||
|
fn from(other: &ImportType) -> Self {
|
||||||
|
// TODO: double check that freeing String as `Vec<u8>` is valid
|
||||||
|
let name = {
|
||||||
|
let mut heap_str: Box<str> = other.name().to_string().into_boxed_str();
|
||||||
|
let char_ptr = heap_str.as_mut_ptr();
|
||||||
|
let str_len = heap_str.bytes().len();
|
||||||
|
let name_inner = wasm_name_t {
|
||||||
|
size: str_len,
|
||||||
|
data: char_ptr,
|
||||||
|
};
|
||||||
|
Box::leak(heap_str);
|
||||||
|
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(name_inner))) }
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: double check that freeing String as `Vec<u8>` is valid
|
||||||
|
let module = {
|
||||||
|
let mut heap_str: Box<str> = other.module().to_string().into_boxed_str();
|
||||||
|
let char_ptr = heap_str.as_mut_ptr();
|
||||||
|
let str_len = heap_str.bytes().len();
|
||||||
|
let name_inner = wasm_name_t {
|
||||||
|
size: str_len,
|
||||||
|
data: char_ptr,
|
||||||
|
};
|
||||||
|
Box::leak(heap_str);
|
||||||
|
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(name_inner))) }
|
||||||
|
};
|
||||||
|
|
||||||
|
let extern_type = {
|
||||||
|
let extern_type: wasm_externtype_t = other.ty().into();
|
||||||
|
unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(extern_type))) }
|
||||||
|
};
|
||||||
|
|
||||||
|
wasm_importtype_t {
|
||||||
|
name,
|
||||||
|
module,
|
||||||
|
extern_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
lib/c-api/src/wasm_c_api/types/memory.rs
Normal file
61
lib/c-api/src/wasm_c_api/types/memory.rs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
use super::wasm_externtype_t;
|
||||||
|
use wasmer::{ExternType, MemoryType, Pages};
|
||||||
|
|
||||||
|
// opaque type wrapping `MemoryType`
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct wasm_memorytype_t {
|
||||||
|
pub(crate) extern_: wasm_externtype_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_memorytype_t {
|
||||||
|
pub(crate) fn as_memorytype(&self) -> &MemoryType {
|
||||||
|
if let ExternType::Memory(ref mt) = self.extern_.inner {
|
||||||
|
mt
|
||||||
|
} else {
|
||||||
|
unreachable!(
|
||||||
|
"Data corruption detected: `wasm_memorytype_t` does not contain a `MemoryType`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_vec!(memorytype);
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_limits_t {
|
||||||
|
pub(crate) min: u32,
|
||||||
|
pub(crate) max: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
||||||
|
let min_pages = Pages(limits.min as _);
|
||||||
|
// TODO: investigate if `0` is in fact a sentinel value here
|
||||||
|
let max_pages = if limits.max == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Pages(limits.max as _))
|
||||||
|
};
|
||||||
|
Box::new(wasm_memorytype_t {
|
||||||
|
extern_: wasm_externtype_t {
|
||||||
|
inner: ExternType::Memory(MemoryType::new(min_pages, max_pages, false)),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_memorytype_delete(_memorytype: Option<Box<wasm_memorytype_t>>) {}
|
||||||
|
|
||||||
|
// TODO: fix memory leak
|
||||||
|
// this function leaks memory because the returned limits pointer is not owned
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_memorytype_limits(mt: &wasm_memorytype_t) -> *const wasm_limits_t {
|
||||||
|
let md = mt.as_memorytype();
|
||||||
|
Box::into_raw(Box::new(wasm_limits_t {
|
||||||
|
min: md.minimum.bytes().0 as _,
|
||||||
|
max: md.maximum.map(|max| max.bytes().0 as _).unwrap_or(0),
|
||||||
|
}))
|
||||||
|
}
|
||||||
27
lib/c-api/src/wasm_c_api/types/mod.rs
Normal file
27
lib/c-api/src/wasm_c_api/types/mod.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
mod byte;
|
||||||
|
mod export;
|
||||||
|
mod extern_;
|
||||||
|
mod frame;
|
||||||
|
mod function;
|
||||||
|
mod global;
|
||||||
|
mod import;
|
||||||
|
mod memory;
|
||||||
|
mod mutability;
|
||||||
|
mod name;
|
||||||
|
mod reference;
|
||||||
|
mod table;
|
||||||
|
mod value;
|
||||||
|
|
||||||
|
pub use byte::*;
|
||||||
|
pub use export::*;
|
||||||
|
pub use extern_::*;
|
||||||
|
pub use frame::*;
|
||||||
|
pub use function::*;
|
||||||
|
pub use global::*;
|
||||||
|
pub use import::*;
|
||||||
|
pub use memory::*;
|
||||||
|
pub use mutability::*;
|
||||||
|
pub use name::*;
|
||||||
|
pub use reference::*;
|
||||||
|
pub use table::*;
|
||||||
|
pub use value::*;
|
||||||
56
lib/c-api/src/wasm_c_api/types/mutability.rs
Normal file
56
lib/c-api/src/wasm_c_api/types/mutability.rs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
use std::convert::TryFrom;
|
||||||
|
use wasmer::Mutability;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub type wasm_mutability_t = u8;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum wasm_mutability_enum {
|
||||||
|
WASM_CONST = 0,
|
||||||
|
WASM_VAR,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_mutability_enum {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn is_mutable(self) -> bool {
|
||||||
|
self == Self::WASM_VAR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<wasm_mutability_t> for wasm_mutability_enum {
|
||||||
|
type Error = &'static str;
|
||||||
|
|
||||||
|
fn try_from(item: wasm_mutability_t) -> Result<Self, Self::Error> {
|
||||||
|
Ok(match item {
|
||||||
|
0 => wasm_mutability_enum::WASM_CONST,
|
||||||
|
1 => wasm_mutability_enum::WASM_VAR,
|
||||||
|
_ => return Err("wasm_mutability_t value out of bounds"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<wasm_mutability_enum> for wasm_mutability_t {
|
||||||
|
fn from(other: wasm_mutability_enum) -> Self {
|
||||||
|
other as wasm_mutability_t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<wasm_mutability_enum> for Mutability {
|
||||||
|
fn from(other: wasm_mutability_enum) -> Self {
|
||||||
|
match other {
|
||||||
|
wasm_mutability_enum::WASM_CONST => Mutability::Const,
|
||||||
|
wasm_mutability_enum::WASM_VAR => Mutability::Var,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Mutability> for wasm_mutability_enum {
|
||||||
|
fn from(other: Mutability) -> Self {
|
||||||
|
match other {
|
||||||
|
Mutability::Const => wasm_mutability_enum::WASM_CONST,
|
||||||
|
Mutability::Var => wasm_mutability_enum::WASM_VAR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
lib/c-api/src/wasm_c_api/types/name.rs
Normal file
4
lib/c-api/src/wasm_c_api/types/name.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
use super::wasm_byte_vec_t;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub type wasm_name_t = wasm_byte_vec_t;
|
||||||
3
lib/c-api/src/wasm_c_api/types/reference.rs
Normal file
3
lib/c-api/src/wasm_c_api/types/reference.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// opaque type over `ExternRef`?
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct wasm_ref_t;
|
||||||
79
lib/c-api/src/wasm_c_api/types/table.rs
Normal file
79
lib/c-api/src/wasm_c_api/types/table.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use super::{wasm_externtype_t, wasm_limits_t, wasm_valtype_delete, wasm_valtype_t};
|
||||||
|
use wasmer::{ExternType, TableType};
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub type wasm_table_size_t = u32;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct wasm_tabletype_t {
|
||||||
|
pub(crate) extern_: wasm_externtype_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_vec!(tabletype);
|
||||||
|
|
||||||
|
impl wasm_tabletype_t {
|
||||||
|
pub(crate) fn as_tabletype(&self) -> &TableType {
|
||||||
|
if let ExternType::Table(ref t) = self.extern_.inner {
|
||||||
|
t
|
||||||
|
} else {
|
||||||
|
unreachable!(
|
||||||
|
"Data corruption detected: `wasm_tabletype_t` does not contain a `TableType`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_new(
|
||||||
|
// own
|
||||||
|
valtype: Box<wasm_valtype_t>,
|
||||||
|
limits: &wasm_limits_t,
|
||||||
|
) -> Box<wasm_tabletype_t> {
|
||||||
|
// TODO: investigate if `0` is in fact a sentinel value here
|
||||||
|
let max_elements = if limits.max == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(limits.max as _)
|
||||||
|
};
|
||||||
|
let out = Box::new(wasm_tabletype_t {
|
||||||
|
extern_: wasm_externtype_t {
|
||||||
|
inner: ExternType::Table(TableType::new(
|
||||||
|
(*valtype).into(),
|
||||||
|
limits.min as _,
|
||||||
|
max_elements,
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wasm_valtype_delete(Some(valtype));
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix memory leak
|
||||||
|
// this function leaks memory because the returned limits pointer is not owned
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_limits(
|
||||||
|
tabletype: &wasm_tabletype_t,
|
||||||
|
) -> *const wasm_limits_t {
|
||||||
|
let tt = tabletype.as_tabletype();
|
||||||
|
Box::into_raw(Box::new(wasm_limits_t {
|
||||||
|
min: tt.minimum as _,
|
||||||
|
max: tt.maximum.unwrap_or(0),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix memory leak
|
||||||
|
// this function leaks memory because the returned limits pointer is not owned
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_element(
|
||||||
|
tabletype: &wasm_tabletype_t,
|
||||||
|
) -> *const wasm_valtype_t {
|
||||||
|
let tt = tabletype.as_tabletype();
|
||||||
|
|
||||||
|
Box::into_raw(Box::new(tt.ty.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_delete(_tabletype: Option<Box<wasm_tabletype_t>>) {}
|
||||||
92
lib/c-api/src/wasm_c_api/types/value.rs
Normal file
92
lib/c-api/src/wasm_c_api/types/value.rs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
use super::super::value::wasm_valkind_t;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use wasmer::ValType;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum wasm_valkind_enum {
|
||||||
|
WASM_I32 = 0,
|
||||||
|
WASM_I64 = 1,
|
||||||
|
WASM_F32 = 2,
|
||||||
|
WASM_F64 = 3,
|
||||||
|
WASM_ANYREF = 128,
|
||||||
|
WASM_FUNCREF = 129,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ValType> for wasm_valkind_enum {
|
||||||
|
fn from(other: ValType) -> Self {
|
||||||
|
match other {
|
||||||
|
ValType::I32 => Self::WASM_I32,
|
||||||
|
ValType::I64 => Self::WASM_I64,
|
||||||
|
ValType::F32 => Self::WASM_F32,
|
||||||
|
ValType::F64 => Self::WASM_F64,
|
||||||
|
ValType::V128 => todo!("no v128 type in Wasm C API yet!"),
|
||||||
|
ValType::ExternRef => Self::WASM_ANYREF,
|
||||||
|
ValType::FuncRef => Self::WASM_FUNCREF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<wasm_valkind_enum> for ValType {
|
||||||
|
fn from(other: wasm_valkind_enum) -> Self {
|
||||||
|
use wasm_valkind_enum::*;
|
||||||
|
match other {
|
||||||
|
WASM_I32 => ValType::I32,
|
||||||
|
WASM_I64 => ValType::I64,
|
||||||
|
WASM_F32 => ValType::F32,
|
||||||
|
WASM_F64 => ValType::F64,
|
||||||
|
WASM_ANYREF => ValType::ExternRef,
|
||||||
|
WASM_FUNCREF => ValType::FuncRef,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_valtype_t {
|
||||||
|
valkind: wasm_valkind_enum,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for wasm_valtype_t {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
valkind: wasm_valkind_enum::WASM_I32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_declare_boxed_vec!(valtype);
|
||||||
|
|
||||||
|
impl From<wasm_valtype_t> for ValType {
|
||||||
|
fn from(other: wasm_valtype_t) -> Self {
|
||||||
|
other.valkind.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ValType> for wasm_valtype_t {
|
||||||
|
fn from(other: ValType) -> Self {
|
||||||
|
Self {
|
||||||
|
valkind: other.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wasm_valtype_new(kind: wasm_valkind_t) -> Option<Box<wasm_valtype_t>> {
|
||||||
|
let kind_enum = kind.try_into().ok()?;
|
||||||
|
let valtype = wasm_valtype_t { valkind: kind_enum };
|
||||||
|
Some(Box::new(valtype))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_valtype_delete(_valtype: Option<Box<wasm_valtype_t>>) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_valtype_kind(valtype: *const wasm_valtype_t) -> wasm_valkind_t {
|
||||||
|
if valtype.is_null() {
|
||||||
|
// TODO: handle error
|
||||||
|
panic!("wasm_valtype_kind: argument is null pointer");
|
||||||
|
}
|
||||||
|
return (*valtype).valkind as wasm_valkind_t;
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#[macro_export]
|
|
||||||
macro_rules! c_try {
|
|
||||||
($expr:expr) => {{
|
|
||||||
let res: Result<_, _> = $expr;
|
|
||||||
match res {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => {
|
|
||||||
crate::error::update_last_error(err);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
($expr:expr, $e:expr) => {{
|
|
||||||
let opt: Option<_> = $expr;
|
|
||||||
c_try!(opt.ok_or_else(|| $e))
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use super::{wasm_ref_t, wasm_valkind_enum};
|
use super::types::{wasm_ref_t, wasm_valkind_enum};
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use wasmer::Val;
|
use wasmer::Val;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use super::{
|
|||||||
};
|
};
|
||||||
// required due to really weird Rust resolution rules for macros
|
// required due to really weird Rust resolution rules for macros
|
||||||
// https://github.com/rust-lang/rust/issues/57966
|
// https://github.com/rust-lang/rust/issues/57966
|
||||||
use crate::c_try;
|
|
||||||
use crate::error::{update_last_error, CApiError};
|
use crate::error::{update_last_error, CApiError};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|||||||
Reference in New Issue
Block a user