Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions benches/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@ fn wasm_to_host(c: &mut Criterion) {

let mut untyped = Linker::new(&engine);
untyped
.func_new("", "nop", FuncType::new([], []), |_, _, _| Ok(()))
.func_new("", "nop", FuncType::new(&engine, [], []), |_, _, _| Ok(()))
.unwrap();
let ty = FuncType::new([ValType::I32, ValType::I64], [ValType::F32]);
let ty = FuncType::new(&engine, [ValType::I32, ValType::I64], [ValType::F32]);
untyped
.func_new(
"",
Expand Down Expand Up @@ -336,9 +336,9 @@ fn wasm_to_host(c: &mut Criterion) {
unsafe {
let mut unchecked = Linker::new(&engine);
unchecked
.func_new_unchecked("", "nop", FuncType::new([], []), |_, _| Ok(()))
.func_new_unchecked("", "nop", FuncType::new(&engine, [], []), |_, _| Ok(()))
.unwrap();
let ty = FuncType::new([ValType::I32, ValType::I64], [ValType::F32]);
let ty = FuncType::new(&engine, [ValType::I32, ValType::I64], [ValType::F32]);
unchecked
.func_new_unchecked("", "nop-params-and-results", ty, |mut caller, space| {
match Val::from_raw(&mut caller, space[0], ValType::I32) {
Expand Down
2 changes: 1 addition & 1 deletion benches/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ fn bench_host_wasm_frames_traps(c: &mut Criterion) {
let mut store = Store::new(&engine, ());
let host_func = Func::new(
&mut store,
FuncType::new(vec![ValType::I32], vec![]),
FuncType::new(&engine, vec![ValType::I32], vec![]),
|mut caller, args, _results| {
let f = caller.get_export("f").unwrap();
let f = f.into_func().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/c-api/src/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ pub unsafe extern "C" fn wasmtime_linker_define_async_func(
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
) -> Option<Box<wasmtime_error_t>> {
let ty = ty.ty().ty.clone();
let ty = ty.ty().ty(linker.linker.engine());
let module = to_str!(module, module_len);
let name = to_str!(name, name_len);
let cb = c_async_callback_to_rust_fn(callback, data, finalizer);
Expand Down
6 changes: 4 additions & 2 deletions crates/c-api/src/extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {

#[no_mangle]
pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
Box::new(wasm_externtype_t::new(e.which.ty(&e.store.context())))
Box::new(wasm_externtype_t::from_extern_type(
e.which.ty(&e.store.context()),
))
}

#[no_mangle]
Expand Down Expand Up @@ -135,5 +137,5 @@ pub unsafe extern "C" fn wasmtime_extern_type(
store: CStoreContext<'_>,
e: &wasmtime_extern_t,
) -> Box<wasm_externtype_t> {
Box::new(wasm_externtype_t::new(e.to_extern().ty(store)))
Box::new(wasm_externtype_t::from_extern_type(e.to_extern().ty(store)))
}
6 changes: 3 additions & 3 deletions crates/c-api/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ unsafe fn create_function(
+ Sync
+ 'static,
) -> Box<wasm_func_t> {
let ty = ty.ty().ty.clone();
let ty = ty.ty().ty(store.store.context().engine());
let func = Func::new(
store.store.context_mut(),
ty,
Expand Down Expand Up @@ -228,7 +228,7 @@ pub unsafe extern "C" fn wasmtime_func_new(
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
func: &mut Func,
) {
let ty = ty.ty().ty.clone();
let ty = ty.ty().ty(store.engine());
let cb = c_callback_to_rust_fn(callback, data, finalizer);
let f = Func::new(store, ty, cb);
*func = f;
Expand Down Expand Up @@ -293,7 +293,7 @@ pub unsafe extern "C" fn wasmtime_func_new_unchecked(
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
func: &mut Func,
) {
let ty = ty.ty().ty.clone();
let ty = ty.ty().ty(store.engine());
let cb = c_unchecked_callback_to_rust_fn(callback, data, finalizer);
*func = Func::new_unchecked(store, ty, cb);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/c-api/src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub unsafe extern "C" fn wasmtime_linker_define_func(
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
) -> Option<Box<wasmtime_error_t>> {
let ty = ty.ty().ty.clone();
let ty = ty.ty().ty(linker.linker.engine());
let module = to_str!(module, module_len);
let name = to_str!(name, name_len);
let cb = crate::func::c_callback_to_rust_fn(callback, data, finalizer);
Expand All @@ -88,7 +88,7 @@ pub unsafe extern "C" fn wasmtime_linker_define_func_unchecked(
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
) -> Option<Box<wasmtime_error_t>> {
let ty = ty.ty().ty.clone();
let ty = ty.ty().ty(linker.linker.engine());
let module = to_str!(module, module_len);
let name = to_str!(name, name_len);
let cb = crate::func::c_unchecked_callback_to_rust_fn(callback, data, finalizer);
Expand Down
6 changes: 3 additions & 3 deletions crates/c-api/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
handle_result, wasm_byte_vec_t, wasm_engine_t, wasm_exporttype_t, wasm_exporttype_vec_t,
wasm_importtype_t, wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t,
wasm_importtype_t, wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t, CExternType,
};
use anyhow::Context;
use std::ffi::CStr;
Expand Down Expand Up @@ -53,7 +53,7 @@ fn fill_exports(module: &Module, out: &mut wasm_exporttype_vec_t) {
.map(|e| {
Some(Box::new(wasm_exporttype_t::new(
e.name().to_owned(),
e.ty(),
CExternType::new(e.ty()),
)))
})
.collect::<Vec<_>>();
Expand All @@ -67,7 +67,7 @@ fn fill_imports(module: &Module, out: &mut wasm_importtype_vec_t) {
Some(Box::new(wasm_importtype_t::new(
i.module().to_owned(),
i.name().to_owned(),
i.ty(),
CExternType::new(i.ty()),
)))
})
.collect::<Vec<_>>();
Expand Down
11 changes: 5 additions & 6 deletions crates/c-api/src/types/export.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
use crate::{wasm_externtype_t, wasm_name_t};
use crate::{wasm_externtype_t, wasm_name_t, CExternType};
use once_cell::unsync::OnceCell;
use wasmtime::ExternType;

#[repr(C)]
#[derive(Clone)]
pub struct wasm_exporttype_t {
name: String,
ty: ExternType,
ty: CExternType,
name_cache: OnceCell<wasm_name_t>,
type_cache: OnceCell<wasm_externtype_t>,
}

wasmtime_c_api_macros::declare_ty!(wasm_exporttype_t);

impl wasm_exporttype_t {
pub(crate) fn new(name: String, ty: ExternType) -> wasm_exporttype_t {
pub(crate) fn new(name: String, ty: CExternType) -> wasm_exporttype_t {
wasm_exporttype_t {
name,
ty,
Expand All @@ -31,7 +30,7 @@ pub extern "C" fn wasm_exporttype_new(
) -> Option<Box<wasm_exporttype_t>> {
let name = name.take();
let name = String::from_utf8(name).ok()?;
Some(Box::new(wasm_exporttype_t::new(name, ty.ty())))
Some(Box::new(wasm_exporttype_t::new(name, ty.which.clone())))
}

#[no_mangle]
Expand All @@ -43,5 +42,5 @@ pub extern "C" fn wasm_exporttype_name(et: &wasm_exporttype_t) -> &wasm_name_t {
#[no_mangle]
pub extern "C" fn wasm_exporttype_type(et: &wasm_exporttype_t) -> &wasm_externtype_t {
et.type_cache
.get_or_init(|| wasm_externtype_t::new(et.ty.clone()))
.get_or_init(|| wasm_externtype_t::from_cextern_type(et.ty.clone()))
}
29 changes: 15 additions & 14 deletions crates/c-api/src/types/extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ pub(crate) enum CExternType {
Table(CTableType),
}

impl CExternType {
pub(crate) fn new(ty: ExternType) -> CExternType {
match ty {
ExternType::Func(f) => CExternType::Func(CFuncType::new(f)),
ExternType::Global(f) => CExternType::Global(CGlobalType::new(f)),
ExternType::Memory(f) => CExternType::Memory(CMemoryType::new(f)),
ExternType::Table(f) => CExternType::Table(CTableType::new(f)),
}
}
}

pub type wasm_externkind_t = u8;

pub const WASM_EXTERN_FUNC: wasm_externkind_t = 0;
Expand All @@ -26,24 +37,14 @@ pub const WASM_EXTERN_TABLE: wasm_externkind_t = 2;
pub const WASM_EXTERN_MEMORY: wasm_externkind_t = 3;

impl wasm_externtype_t {
pub(crate) fn new(ty: ExternType) -> wasm_externtype_t {
pub(crate) fn from_extern_type(ty: ExternType) -> wasm_externtype_t {
wasm_externtype_t {
which: match ty {
ExternType::Func(f) => CExternType::Func(CFuncType::new(f)),
ExternType::Global(f) => CExternType::Global(CGlobalType::new(f)),
ExternType::Memory(f) => CExternType::Memory(CMemoryType::new(f)),
ExternType::Table(f) => CExternType::Table(CTableType::new(f)),
},
which: CExternType::new(ty),
}
}

pub(crate) fn ty(&self) -> ExternType {
match &self.which {
CExternType::Func(f) => ExternType::Func(f.ty.clone()),
CExternType::Table(f) => ExternType::Table(f.ty.clone()),
CExternType::Global(f) => ExternType::Global(f.ty.clone()),
CExternType::Memory(f) => ExternType::Memory(f.ty.clone()),
}
pub(crate) fn from_cextern_type(ty: CExternType) -> wasm_externtype_t {
wasm_externtype_t { which: ty }
}
}

Expand Down
122 changes: 110 additions & 12 deletions crates/c-api/src/types/func.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::{wasm_externtype_t, wasm_valtype_t, wasm_valtype_vec_t, CExternType};
use once_cell::unsync::OnceCell;
use wasmtime::FuncType;
use std::{
mem,
sync::{Arc, Mutex},
};
use wasmtime::{Engine, FuncType, ValType};

#[repr(transparent)]
#[derive(Clone)]
Expand All @@ -10,17 +14,91 @@ pub struct wasm_functype_t {

wasmtime_c_api_macros::declare_ty!(wasm_functype_t);

#[derive(Clone)]
enum LazyFuncType {
Lazy {
params: Vec<ValType>,
results: Vec<ValType>,
},
FuncType(FuncType),
}

impl LazyFuncType {
pub(crate) fn force(&mut self, engine: &Engine) -> FuncType {
match self {
LazyFuncType::FuncType(ty) => ty.clone(),
LazyFuncType::Lazy { params, results } => {
let params = mem::take(params);
let results = mem::take(results);
let ty = FuncType::new(engine, params, results);
*self = LazyFuncType::FuncType(ty.clone());
ty
}
}
}

fn params(&self) -> impl ExactSizeIterator<Item = ValType> + '_ {
match self {
LazyFuncType::Lazy { params, .. } => LazyFuncTypeIter::Lazy(params.iter()),
LazyFuncType::FuncType(f) => LazyFuncTypeIter::FuncType(f.params()),
}
}

fn results(&self) -> impl ExactSizeIterator<Item = ValType> + '_ {
match self {
LazyFuncType::Lazy { results, .. } => LazyFuncTypeIter::Lazy(results.iter()),
LazyFuncType::FuncType(f) => LazyFuncTypeIter::FuncType(f.results()),
}
}
}

enum LazyFuncTypeIter<'a, T> {
Lazy(std::slice::Iter<'a, ValType>),
FuncType(T),
}

impl<'a, T> Iterator for LazyFuncTypeIter<'a, T>
where
T: Iterator<Item = ValType>,
{
type Item = ValType;

fn next(&mut self) -> Option<Self::Item> {
match self {
LazyFuncTypeIter::FuncType(i) => i.next(),
LazyFuncTypeIter::Lazy(i) => i.next().cloned(),
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
match self {
LazyFuncTypeIter::FuncType(i) => i.size_hint(),
LazyFuncTypeIter::Lazy(i) => i.size_hint(),
}
}
}

impl<'a, T> ExactSizeIterator for LazyFuncTypeIter<'a, T> where T: ExactSizeIterator<Item = ValType> {}

#[derive(Clone)]
pub(crate) struct CFuncType {
pub(crate) ty: FuncType,
ty: Arc<Mutex<LazyFuncType>>,
params_cache: OnceCell<wasm_valtype_vec_t>,
returns_cache: OnceCell<wasm_valtype_vec_t>,
}

impl wasm_functype_t {
pub(crate) fn new(ty: FuncType) -> wasm_functype_t {
wasm_functype_t {
ext: wasm_externtype_t::new(ty.into()),
ext: wasm_externtype_t::from_extern_type(ty.into()),
}
}

pub(crate) fn lazy(params: Vec<ValType>, results: Vec<ValType>) -> wasm_functype_t {
wasm_functype_t {
ext: wasm_externtype_t::from_cextern_type(CExternType::Func(CFuncType::lazy(
params, results,
))),
}
}

Expand All @@ -42,30 +120,50 @@ impl wasm_functype_t {
impl CFuncType {
pub(crate) fn new(ty: FuncType) -> CFuncType {
CFuncType {
ty,
ty: Arc::new(Mutex::new(LazyFuncType::FuncType(ty))),
params_cache: OnceCell::new(),
returns_cache: OnceCell::new(),
}
}

pub(crate) fn lazy(params: Vec<ValType>, results: Vec<ValType>) -> CFuncType {
CFuncType {
ty: Arc::new(Mutex::new(LazyFuncType::Lazy { params, results })),
params_cache: OnceCell::new(),
returns_cache: OnceCell::new(),
}
}

pub(crate) fn ty(&self, engine: &Engine) -> FuncType {
let mut ty = self.ty.lock().unwrap();
ty.force(engine)
}
}

#[no_mangle]
pub extern "C" fn wasm_functype_new(
params: &mut wasm_valtype_vec_t,
results: &mut wasm_valtype_vec_t,
) -> Box<wasm_functype_t> {
let params = params.take().into_iter().map(|vt| vt.unwrap().ty.clone());
let results = results.take().into_iter().map(|vt| vt.unwrap().ty.clone());
let functype = FuncType::new(params, results);
Box::new(wasm_functype_t::new(functype))
let params = params
.take()
.into_iter()
.map(|vt| vt.unwrap().ty.clone())
.collect();
let results = results
.take()
.into_iter()
.map(|vt| vt.unwrap().ty.clone())
.collect();
Box::new(wasm_functype_t::lazy(params, results))
}

#[no_mangle]
pub extern "C" fn wasm_functype_params(ft: &wasm_functype_t) -> &wasm_valtype_vec_t {
let ft = ft.ty();
ft.params_cache.get_or_init(|| {
ft.ty
.params()
let ty = ft.ty.lock().unwrap();
ty.params()
.map(|p| Some(Box::new(wasm_valtype_t { ty: p.clone() })))
.collect::<Vec<_>>()
.into()
Expand All @@ -76,8 +174,8 @@ pub extern "C" fn wasm_functype_params(ft: &wasm_functype_t) -> &wasm_valtype_ve
pub extern "C" fn wasm_functype_results(ft: &wasm_functype_t) -> &wasm_valtype_vec_t {
let ft = ft.ty();
ft.returns_cache.get_or_init(|| {
ft.ty
.results()
let ty = ft.ty.lock().unwrap();
ty.results()
.map(|p| Some(Box::new(wasm_valtype_t { ty: p.clone() })))
.collect::<Vec<_>>()
.into()
Expand Down
Loading