mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 05:08:19 +00:00
feat(c-api) Move instance into its own module.
This commit is contained in:
104
lib/c-api/src/wasm_c_api/instance.rs
Normal file
104
lib/c-api/src/wasm_c_api/instance.rs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
use super::{wasm_extern_t, wasm_extern_vec_t, wasm_module_t, wasm_store_t, wasm_trap_t};
|
||||||
|
use crate::c_try;
|
||||||
|
use crate::ordered_resolver::OrderedResolver;
|
||||||
|
use std::mem;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use wasmer::{Extern, Instance};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_instance_t {
|
||||||
|
pub(crate) inner: Arc<Instance>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CArrayIter<T: Sized + 'static> {
|
||||||
|
cur_entry: *const *const T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Sized + 'static> CArrayIter<T> {
|
||||||
|
fn new(array: *const *const T) -> Option<Self> {
|
||||||
|
if array.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(CArrayIter { cur_entry: array })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Sized + 'static> Iterator for CArrayIter<T> {
|
||||||
|
type Item = &'static T;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let next_entry_candidate = unsafe { *self.cur_entry };
|
||||||
|
if next_entry_candidate.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.cur_entry = unsafe { self.cur_entry.add(1) };
|
||||||
|
Some(unsafe { &*next_entry_candidate })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads from null-terminated array of `wasm_extern_t`s
|
||||||
|
unsafe fn argument_import_iter(
|
||||||
|
imports: *const *const wasm_extern_t,
|
||||||
|
) -> Box<dyn Iterator<Item = &'static wasm_extern_t>> {
|
||||||
|
CArrayIter::new(imports)
|
||||||
|
.map(|it| Box::new(it) as _)
|
||||||
|
.unwrap_or_else(|| Box::new(std::iter::empty()) as _)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_instance_new(
|
||||||
|
store: Option<NonNull<wasm_store_t>>,
|
||||||
|
module: &wasm_module_t,
|
||||||
|
imports: *const *const wasm_extern_t,
|
||||||
|
// own
|
||||||
|
_traps: *mut *mut wasm_trap_t,
|
||||||
|
) -> Option<Box<wasm_instance_t>> {
|
||||||
|
let wasm_module = &module.inner;
|
||||||
|
let module_imports = wasm_module.imports();
|
||||||
|
let module_import_count = module_imports.len();
|
||||||
|
let imports = argument_import_iter(imports);
|
||||||
|
let resolver: OrderedResolver = imports
|
||||||
|
.map(|imp| &imp.inner)
|
||||||
|
.take(module_import_count)
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let instance = Arc::new(c_try!(Instance::new(wasm_module, &resolver)));
|
||||||
|
Some(Box::new(wasm_instance_t { inner: instance }))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_instance_delete(_instance: Option<Box<wasm_instance_t>>) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_instance_exports(
|
||||||
|
instance: &wasm_instance_t,
|
||||||
|
// TODO: review types on wasm_declare_vec, handle the optional pointer part properly
|
||||||
|
out: &mut wasm_extern_vec_t,
|
||||||
|
) {
|
||||||
|
let instance = &instance.inner;
|
||||||
|
let mut extern_vec = instance
|
||||||
|
.exports
|
||||||
|
.iter()
|
||||||
|
.map(|(name, r#extern)| {
|
||||||
|
let function = if let Extern::Function { .. } = r#extern {
|
||||||
|
instance.exports.get_function(&name).ok().cloned()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Box::into_raw(Box::new(wasm_extern_t {
|
||||||
|
instance: Some(Arc::clone(instance)),
|
||||||
|
inner: r#extern.clone(),
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.collect::<Vec<*mut wasm_extern_t>>();
|
||||||
|
extern_vec.shrink_to_fit();
|
||||||
|
|
||||||
|
out.size = extern_vec.len();
|
||||||
|
out.data = extern_vec.as_mut_ptr();
|
||||||
|
// TODO: double check that the destructor will work correctly here
|
||||||
|
mem::forget(extern_vec);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod externals;
|
pub mod externals;
|
||||||
|
pub mod instance;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
pub mod store;
|
pub mod store;
|
||||||
pub(crate) mod utils;
|
pub(crate) mod utils;
|
||||||
@@ -12,7 +13,6 @@ pub mod wasi;
|
|||||||
// required due to really weird Rust resolution rules
|
// required due to really weird Rust resolution rules
|
||||||
// https://github.com/rust-lang/rust/issues/57966
|
// https://github.com/rust-lang/rust/issues/57966
|
||||||
use crate::c_try;
|
use crate::c_try;
|
||||||
use crate::ordered_resolver::OrderedResolver;
|
|
||||||
use externals::function::wasm_func_t;
|
use externals::function::wasm_func_t;
|
||||||
use externals::global::wasm_global_t;
|
use externals::global::wasm_global_t;
|
||||||
use externals::memory::wasm_memory_t;
|
use externals::memory::wasm_memory_t;
|
||||||
@@ -33,103 +33,6 @@ use wasmer::{
|
|||||||
#[cfg(feature = "jit")]
|
#[cfg(feature = "jit")]
|
||||||
use wasmer_engine_jit::JIT;
|
use wasmer_engine_jit::JIT;
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct wasm_instance_t {
|
|
||||||
inner: Arc<Instance>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_instance_new(
|
|
||||||
store: Option<NonNull<wasm_store_t>>,
|
|
||||||
module: &wasm_module_t,
|
|
||||||
imports: *const *const wasm_extern_t,
|
|
||||||
// own
|
|
||||||
_traps: *mut *mut wasm_trap_t,
|
|
||||||
) -> Option<Box<wasm_instance_t>> {
|
|
||||||
let wasm_module = &module.inner;
|
|
||||||
let module_imports = wasm_module.imports();
|
|
||||||
let module_import_count = module_imports.len();
|
|
||||||
let imports = argument_import_iter(imports);
|
|
||||||
let resolver: OrderedResolver = imports
|
|
||||||
.map(|imp| &imp.inner)
|
|
||||||
.take(module_import_count)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let instance = Arc::new(c_try!(Instance::new(wasm_module, &resolver)));
|
|
||||||
Some(Box::new(wasm_instance_t { inner: instance }))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_instance_delete(_instance: Option<Box<wasm_instance_t>>) {}
|
|
||||||
|
|
||||||
struct CArrayIter<T: Sized + 'static> {
|
|
||||||
cur_entry: *const *const T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized + 'static> CArrayIter<T> {
|
|
||||||
fn new(array: *const *const T) -> Option<Self> {
|
|
||||||
if array.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(CArrayIter { cur_entry: array })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized + 'static> Iterator for CArrayIter<T> {
|
|
||||||
type Item = &'static T;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let next_entry_candidate = unsafe { *self.cur_entry };
|
|
||||||
if next_entry_candidate.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
self.cur_entry = unsafe { self.cur_entry.add(1) };
|
|
||||||
Some(unsafe { &*next_entry_candidate })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reads from null-terminated array of `wasm_extern_t`s
|
|
||||||
unsafe fn argument_import_iter(
|
|
||||||
imports: *const *const wasm_extern_t,
|
|
||||||
) -> Box<dyn Iterator<Item = &'static wasm_extern_t>> {
|
|
||||||
CArrayIter::new(imports)
|
|
||||||
.map(|it| Box::new(it) as _)
|
|
||||||
.unwrap_or_else(|| Box::new(std::iter::empty()) as _)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn wasm_instance_exports(
|
|
||||||
instance: &wasm_instance_t,
|
|
||||||
// TODO: review types on wasm_declare_vec, handle the optional pointer part properly
|
|
||||||
out: &mut wasm_extern_vec_t,
|
|
||||||
) {
|
|
||||||
let instance = &instance.inner;
|
|
||||||
let mut extern_vec = instance
|
|
||||||
.exports
|
|
||||||
.iter()
|
|
||||||
.map(|(name, r#extern)| {
|
|
||||||
let function = if let Extern::Function { .. } = r#extern {
|
|
||||||
instance.exports.get_function(&name).ok().cloned()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Box::into_raw(Box::new(wasm_extern_t {
|
|
||||||
instance: Some(Arc::clone(instance)),
|
|
||||||
inner: r#extern.clone(),
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
.collect::<Vec<*mut wasm_extern_t>>();
|
|
||||||
extern_vec.shrink_to_fit();
|
|
||||||
|
|
||||||
out.size = extern_vec.len();
|
|
||||||
out.data = extern_vec.as_mut_ptr();
|
|
||||||
// TODO: double check that the destructor will work correctly here
|
|
||||||
mem::forget(extern_vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_func_as_extern(
|
pub unsafe extern "C" fn wasm_func_as_extern(
|
||||||
func_ptr: Option<NonNull<wasm_func_t>>,
|
func_ptr: Option<NonNull<wasm_func_t>>,
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
mod capture_files;
|
mod capture_files;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
externals::memory::wasm_memory_t, wasm_extern_t, wasm_func_t, wasm_instance_t, wasm_module_t,
|
externals::memory::wasm_memory_t, instance::wasm_instance_t, wasm_extern_t, wasm_func_t,
|
||||||
wasm_store_t,
|
wasm_module_t, wasm_store_t,
|
||||||
};
|
};
|
||||||
// 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
|
||||||
|
|||||||
Reference in New Issue
Block a user