mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 14:18:20 +00:00
Add wip solution to wasm_extern_as_ no allocation
This commit is contained in:
28
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
28
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
@@ -2,17 +2,27 @@ use super::super::store::wasm_store_t;
|
|||||||
use super::super::trap::wasm_trap_t;
|
use super::super::trap::wasm_trap_t;
|
||||||
use super::super::types::{wasm_functype_t, wasm_valkind_enum};
|
use super::super::types::{wasm_functype_t, wasm_valkind_enum};
|
||||||
use super::super::value::{wasm_val_inner, wasm_val_t, wasm_val_vec_t};
|
use super::super::value::{wasm_val_inner, wasm_val_t, wasm_val_vec_t};
|
||||||
|
use super::CApiExternTag;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmer::{Function, Instance, RuntimeError, Val};
|
use wasmer::{Function, RuntimeError, Val};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct wasm_func_t {
|
pub struct wasm_func_t {
|
||||||
pub(crate) inner: Function,
|
pub(crate) tag: CApiExternTag,
|
||||||
// this is how we ensure the instance stays alive
|
pub(crate) inner: Box<Function>,
|
||||||
pub(crate) instance: Option<Arc<Instance>>,
|
}
|
||||||
|
|
||||||
|
impl wasm_func_t {
|
||||||
|
pub(crate) fn new(function: Function) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: CApiExternTag::Function,
|
||||||
|
inner: Box::new(function),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
@@ -80,10 +90,7 @@ pub unsafe extern "C" fn wasm_func_new(
|
|||||||
};
|
};
|
||||||
let function = Function::new(&store.inner, func_sig, inner_callback);
|
let function = Function::new(&store.inner, func_sig, inner_callback);
|
||||||
|
|
||||||
Some(Box::new(wasm_func_t {
|
Some(Box::new(wasm_func_t { inner: function }))
|
||||||
instance: None,
|
|
||||||
inner: function,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -172,10 +179,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
|||||||
trampoline,
|
trampoline,
|
||||||
);
|
);
|
||||||
|
|
||||||
Some(Box::new(wasm_func_t {
|
Some(Box::new(wasm_func_t { inner: function }))
|
||||||
instance: None,
|
|
||||||
inner: function,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
15
lib/c-api/src/wasm_c_api/externals/global.rs
vendored
15
lib/c-api/src/wasm_c_api/externals/global.rs
vendored
@@ -1,14 +1,25 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
use super::super::types::wasm_globaltype_t;
|
use super::super::types::wasm_globaltype_t;
|
||||||
use super::super::value::wasm_val_t;
|
use super::super::value::wasm_val_t;
|
||||||
|
use super::CApiExternTag;
|
||||||
use crate::error::update_last_error;
|
use crate::error::update_last_error;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use wasmer::{Global, Val};
|
use wasmer::{Global, Val};
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct wasm_global_t {
|
pub struct wasm_global_t {
|
||||||
// maybe needs to hold onto instance
|
pub(crate) tag: CApiExternTag,
|
||||||
pub(crate) inner: Global,
|
pub(crate) inner: Box<Global>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_global_t {
|
||||||
|
pub(crate) fn new(global: Global) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: CApiExternTag::Global,
|
||||||
|
inner: Box::new(global),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
15
lib/c-api/src/wasm_c_api/externals/memory.rs
vendored
15
lib/c-api/src/wasm_c_api/externals/memory.rs
vendored
@@ -1,12 +1,23 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
use super::super::types::wasm_memorytype_t;
|
use super::super::types::wasm_memorytype_t;
|
||||||
|
use super::CApiExternTag;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use wasmer::{Memory, Pages};
|
use wasmer::{Memory, Pages};
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct wasm_memory_t {
|
pub struct wasm_memory_t {
|
||||||
// maybe needs to hold onto instance
|
pub(crate) tag: CApiExternTag,
|
||||||
pub(crate) inner: Memory,
|
pub(crate) inner: Box<Memory>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_memory_t {
|
||||||
|
pub(crate) fn new(memory: Memory) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: CApiExternTag::Memory,
|
||||||
|
inner: Box::new(memory),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
90
lib/c-api/src/wasm_c_api/externals/mod.rs
vendored
90
lib/c-api/src/wasm_c_api/externals/mod.rs
vendored
@@ -12,10 +12,94 @@ use wasmer::{Extern, Instance};
|
|||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct wasm_extern_t {
|
pub struct wasm_extern_t {
|
||||||
// this is how we ensure the instance stays alive
|
pub(crate) inner: wasm_extern_inner,
|
||||||
pub(crate) instance: Option<Arc<Instance>>,
|
}
|
||||||
pub(crate) inner: Extern,
|
|
||||||
|
/// All elements in this union must be `repr(C)` and have a
|
||||||
|
/// `CApiExternTag` as their first element.
|
||||||
|
pub(crate) union wasm_extern_inner {
|
||||||
|
function: wasm_func_t,
|
||||||
|
memory: wasm_memory_t,
|
||||||
|
global: wasm_global_t,
|
||||||
|
table: wasm_table_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod extern_tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn externs_are_the_same_size() {
|
||||||
|
use std::mem::size_of;
|
||||||
|
assert_eq!(size_of::<wasm_extern_t>(), size_of::<wasm_func_t>());
|
||||||
|
assert_eq!(size_of::<wasm_extern_t>(), size_of::<wasm_memory_t>());
|
||||||
|
assert_eq!(size_of::<wasm_extern_t>(), size_of::<wasm_global_t>());
|
||||||
|
assert_eq!(size_of::<wasm_extern_t>(), size_of::<wasm_table_t>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_extern_t {
|
||||||
|
pub(crate) fn get_tag(&self) -> CApiExternTag {
|
||||||
|
unsafe { self.inner.function.tag }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ty(&self) -> ExternType {
|
||||||
|
match self.get_tag() {
|
||||||
|
CApiExternTag::Function => unsafe { self.inner.function.inner.ty() },
|
||||||
|
CApiExternTag::Memory => unsafe { self.inner.memory.inner.ty() },
|
||||||
|
CApiExternTag::Global => unsafe { self.inner.global.inner.ty() },
|
||||||
|
CApiExternTag::Table => unsafe { self.inner.table.inner.ty() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Extern> for wasm_extern_t {
|
||||||
|
fn from(other: Extern) -> Self {
|
||||||
|
match other {
|
||||||
|
Extern::Function(function) => Self {
|
||||||
|
inner: wasm_extern_inner {
|
||||||
|
function: wasm_func_t::new(function),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Extern::Memory(memory) => Self {
|
||||||
|
inner: wasm_extern_inner {
|
||||||
|
memory: wasm_memory_t::new(memory),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Extern::Table(table) => Self {
|
||||||
|
inner: wasm_extern_inner {
|
||||||
|
table: wasm_table_t::new(table),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Extern::Global(global) => Self {
|
||||||
|
inner: wasm_extern_inner {
|
||||||
|
global: wasm_global_t::new(global),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<wasm_extern_t> for Extern {
|
||||||
|
fn from(other: wasm_extern_t) -> Self {
|
||||||
|
match other.get_tag() {
|
||||||
|
CApiExternTag::Function => unsafe { self.inner.function.inner.clone().into() },
|
||||||
|
CApiExternTag::Memory => unsafe { self.inner.memory.inner.clone().into() },
|
||||||
|
CApiExternTag::Table => unsafe { self.inner.table.inner.clone().into() },
|
||||||
|
CApiExternTag::Global => unsafe { self.inner.global.inner.clone().into() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub(crate) enum CApiExternTag {
|
||||||
|
Function,
|
||||||
|
Global,
|
||||||
|
Table,
|
||||||
|
Memory,
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_declare_boxed_vec!(extern);
|
wasm_declare_boxed_vec!(extern);
|
||||||
|
|||||||
15
lib/c-api/src/wasm_c_api/externals/table.rs
vendored
15
lib/c-api/src/wasm_c_api/externals/table.rs
vendored
@@ -1,11 +1,22 @@
|
|||||||
use super::super::store::wasm_store_t;
|
use super::super::store::wasm_store_t;
|
||||||
use super::super::types::{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 super::CApiExternTag;
|
||||||
use wasmer::Table;
|
use wasmer::Table;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct wasm_table_t {
|
pub struct wasm_table_t {
|
||||||
// maybe needs to hold onto instance
|
pub(crate) tag: CApiExternTag,
|
||||||
pub(crate) inner: Table,
|
pub(crate) inner: Box<Table>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl wasm_table_t {
|
||||||
|
pub(crate) fn new(table: Table) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: CApiExternTag::Table,
|
||||||
|
inner: Box::new(table),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -192,10 +192,7 @@ pub unsafe extern "C" fn wasm_instance_exports(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Box::into_raw(Box::new(wasm_extern_t {
|
Box::into_raw(Box::new(r#extern.clone().into()))
|
||||||
instance: Some(Arc::clone(instance)),
|
|
||||||
inner: r#extern.clone(),
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<*mut wasm_extern_t>>();
|
.collect::<Vec<*mut wasm_extern_t>>();
|
||||||
extern_vec.shrink_to_fit();
|
extern_vec.shrink_to_fit();
|
||||||
|
|||||||
@@ -85,12 +85,12 @@ impl From<&ExternType> for wasm_externtype_t {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_extern_type(r#extern: &wasm_extern_t) -> Box<wasm_externtype_t> {
|
pub unsafe extern "C" fn wasm_extern_type(r#extern: &wasm_extern_t) -> Box<wasm_externtype_t> {
|
||||||
Box::new(wasm_externtype_t::new(r#extern.inner.ty()))
|
Box::new(wasm_externtype_t::new(r#extern.ty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_extern_kind(r#extern: &wasm_extern_t) -> wasm_externkind_t {
|
pub unsafe extern "C" fn wasm_extern_kind(r#extern: &wasm_extern_t) -> wasm_externkind_t {
|
||||||
wasm_externkind_enum::from(r#extern.inner.ty()) as wasm_externkind_t
|
wasm_externkind_enum::from(r#extern.ty()) as wasm_externkind_t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -186,10 +186,7 @@ fn wasi_get_unordered_imports_inner(
|
|||||||
Box::new(wasmer_named_extern_t {
|
Box::new(wasmer_named_extern_t {
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
r#extern: Box::new(wasm_extern_t {
|
r#extern: Box::new(extern_inner.into()),
|
||||||
instance: None,
|
|
||||||
inner: extern_inner,
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
|||||||
@@ -390,10 +390,7 @@ fn wasi_get_imports_inner(
|
|||||||
}));
|
}));
|
||||||
let inner = Extern::from_vm_export(store, export);
|
let inner = Extern::from_vm_export(store, export);
|
||||||
|
|
||||||
Some(Box::new(wasm_extern_t {
|
Some(Box::new(inner.into()))
|
||||||
instance: None,
|
|
||||||
inner,
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
.collect::<Option<Vec<_>>>()?
|
.collect::<Option<Vec<_>>>()?
|
||||||
.into();
|
.into();
|
||||||
@@ -407,10 +404,7 @@ pub unsafe extern "C" fn wasi_get_start_function(
|
|||||||
) -> Option<Box<wasm_func_t>> {
|
) -> Option<Box<wasm_func_t>> {
|
||||||
let start = c_try!(instance.inner.exports.get_function("_start"));
|
let start = c_try!(instance.inner.exports.get_function("_start"));
|
||||||
|
|
||||||
Some(Box::new(wasm_func_t {
|
Some(Box::new(wasm_func_t::new(start.clone())))
|
||||||
inner: start.clone(),
|
|
||||||
instance: Some(instance.inner.clone()),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user