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::types::{wasm_functype_t, wasm_valkind_enum};
|
||||
use super::super::value::{wasm_val_inner, wasm_val_t, wasm_val_vec_t};
|
||||
use super::CApiExternTag;
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::c_void;
|
||||
use std::sync::Arc;
|
||||
use wasmer::{Function, Instance, RuntimeError, Val};
|
||||
use wasmer::{Function, RuntimeError, Val};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
pub struct wasm_func_t {
|
||||
pub(crate) inner: Function,
|
||||
// this is how we ensure the instance stays alive
|
||||
pub(crate) instance: Option<Arc<Instance>>,
|
||||
pub(crate) tag: CApiExternTag,
|
||||
pub(crate) inner: Box<Function>,
|
||||
}
|
||||
|
||||
impl wasm_func_t {
|
||||
pub(crate) fn new(function: Function) -> Self {
|
||||
Self {
|
||||
tag: CApiExternTag::Function,
|
||||
inner: Box::new(function),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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);
|
||||
|
||||
Some(Box::new(wasm_func_t {
|
||||
instance: None,
|
||||
inner: function,
|
||||
}))
|
||||
Some(Box::new(wasm_func_t { inner: function }))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -172,10 +179,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
||||
trampoline,
|
||||
);
|
||||
|
||||
Some(Box::new(wasm_func_t {
|
||||
instance: None,
|
||||
inner: function,
|
||||
}))
|
||||
Some(Box::new(wasm_func_t { inner: function }))
|
||||
}
|
||||
|
||||
#[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::types::wasm_globaltype_t;
|
||||
use super::super::value::wasm_val_t;
|
||||
use super::CApiExternTag;
|
||||
use crate::error::update_last_error;
|
||||
use std::convert::TryInto;
|
||||
use wasmer::{Global, Val};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
pub struct wasm_global_t {
|
||||
// maybe needs to hold onto instance
|
||||
pub(crate) inner: Global,
|
||||
pub(crate) tag: CApiExternTag,
|
||||
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]
|
||||
|
||||
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::types::wasm_memorytype_t;
|
||||
use super::CApiExternTag;
|
||||
use std::mem;
|
||||
use wasmer::{Memory, Pages};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
pub struct wasm_memory_t {
|
||||
// maybe needs to hold onto instance
|
||||
pub(crate) inner: Memory,
|
||||
pub(crate) tag: CApiExternTag,
|
||||
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]
|
||||
|
||||
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)]
|
||||
#[derive(Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct wasm_extern_t {
|
||||
// this is how we ensure the instance stays alive
|
||||
pub(crate) instance: Option<Arc<Instance>>,
|
||||
pub(crate) inner: Extern,
|
||||
pub(crate) inner: wasm_extern_inner,
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
||||
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::types::{wasm_ref_t, wasm_table_size_t, wasm_tabletype_t};
|
||||
use super::CApiExternTag;
|
||||
use wasmer::Table;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
pub struct wasm_table_t {
|
||||
// maybe needs to hold onto instance
|
||||
pub(crate) inner: Table,
|
||||
pub(crate) tag: CApiExternTag,
|
||||
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]
|
||||
|
||||
@@ -192,10 +192,7 @@ pub unsafe extern "C" fn wasm_instance_exports(
|
||||
None
|
||||
};
|
||||
|
||||
Box::into_raw(Box::new(wasm_extern_t {
|
||||
instance: Some(Arc::clone(instance)),
|
||||
inner: r#extern.clone(),
|
||||
}))
|
||||
Box::into_raw(Box::new(r#extern.clone().into()))
|
||||
})
|
||||
.collect::<Vec<*mut wasm_extern_t>>();
|
||||
extern_vec.shrink_to_fit();
|
||||
|
||||
@@ -85,12 +85,12 @@ impl From<&ExternType> for wasm_externtype_t {
|
||||
|
||||
#[no_mangle]
|
||||
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]
|
||||
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]
|
||||
|
||||
@@ -186,10 +186,7 @@ fn wasi_get_unordered_imports_inner(
|
||||
Box::new(wasmer_named_extern_t {
|
||||
module,
|
||||
name,
|
||||
r#extern: Box::new(wasm_extern_t {
|
||||
instance: None,
|
||||
inner: extern_inner,
|
||||
}),
|
||||
r#extern: Box::new(extern_inner.into()),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
|
||||
@@ -390,10 +390,7 @@ fn wasi_get_imports_inner(
|
||||
}));
|
||||
let inner = Extern::from_vm_export(store, export);
|
||||
|
||||
Some(Box::new(wasm_extern_t {
|
||||
instance: None,
|
||||
inner,
|
||||
}))
|
||||
Some(Box::new(inner.into()))
|
||||
})
|
||||
.collect::<Option<Vec<_>>>()?
|
||||
.into();
|
||||
@@ -407,10 +404,7 @@ pub unsafe extern "C" fn wasi_get_start_function(
|
||||
) -> Option<Box<wasm_func_t>> {
|
||||
let start = c_try!(instance.inner.exports.get_function("_start"));
|
||||
|
||||
Some(Box::new(wasm_func_t {
|
||||
inner: start.clone(),
|
||||
instance: Some(instance.inner.clone()),
|
||||
}))
|
||||
Some(Box::new(wasm_func_t::new(start.clone())))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user