Skip to content

Commit

Permalink
Update the C API for the function types refactor
Browse files Browse the repository at this point in the history
prtest:full
  • Loading branch information
fitzgen committed Feb 9, 2024
1 parent 2503a86 commit 3a74942
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 52 deletions.
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
4 changes: 2 additions & 2 deletions crates/c-api/src/extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ 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 +135,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
2 changes: 1 addition & 1 deletion crates/c-api/src/types/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub(crate) struct CGlobalType {
impl wasm_globaltype_t {
pub(crate) fn new(ty: GlobalType) -> wasm_globaltype_t {
wasm_globaltype_t {
ext: wasm_externtype_t::new(ty.into()),
ext: wasm_externtype_t::from_extern_type(ty.into()),
}
}

Expand Down
Loading

0 comments on commit 3a74942

Please sign in to comment.