mirror of
https://github.com/fluencelabs/marine.git
synced 2025-03-15 05:50:49 +00:00
wrap vm::Ctx (with more std::memory::transmute calls)
This commit is contained in:
parent
daaa626c02
commit
4bd99589b0
@ -5,7 +5,7 @@
|
||||
use std::path::PathBuf;
|
||||
use thiserror::Error;
|
||||
use wasmer_core::types::FuncSig;
|
||||
use it_memory_traits::{SequentialMemoryView, SequentialReader, SequentialWriter};
|
||||
use it_memory_traits::{SequentialMemoryView};
|
||||
|
||||
pub struct Value {}
|
||||
|
||||
@ -24,13 +24,14 @@ pub trait WasmBackend: Clone + 'static {
|
||||
type WITMemory: Memory<Self> + it_memory_traits::Memory<Self::WITMemoryView> + Clone + 'static;
|
||||
//type SR: SequentialReader;
|
||||
//type SW: SequentialWriter;
|
||||
type DynamicFunc: DynamicFunc<'static>;
|
||||
type DynamicFunc: DynamicFunc<'static, Self>;
|
||||
type WITMemoryView: for<'a> SequentialMemoryView<'a /* SR = Self::SR, SW = Self::SW*/> + 'static;
|
||||
type FunctionExport: FunctionExport;
|
||||
type M: Module<Self>;
|
||||
type I: Instance<Self>;
|
||||
type Wasi: WasiImplementation<Self>;
|
||||
type Namespace: Namespace<Self>;
|
||||
type ExportContext: ExportContext<Self>;
|
||||
|
||||
fn compile(wasm: &[u8]) -> WasmBackendResult<Self::M>;
|
||||
}
|
||||
@ -56,10 +57,7 @@ pub trait Instance<WB: WasmBackend> {
|
||||
>;
|
||||
fn exports(&self) -> &<WB as WasmBackend>::Exports;
|
||||
fn import_object(&self) -> &<WB as WasmBackend>::IO;
|
||||
|
||||
// maybe hide them inside impl
|
||||
fn context(&self) -> &wasmer_core::vm::Ctx;
|
||||
fn context_mut(&mut self) -> &mut wasmer_core::vm::Ctx;
|
||||
fn memory(&self, memory_index: u32) -> <WB as WasmBackend>::WITMemory;
|
||||
}
|
||||
|
||||
pub trait Exports<WB: WasmBackend> {
|
||||
@ -97,11 +95,6 @@ pub trait ImportObject<WB: WasmBackend>:
|
||||
fn get_memory_env(
|
||||
&self,
|
||||
) -> Option<Export<<WB as WasmBackend>::MemoryExport, <WB as WasmBackend>::FunctionExport>>;
|
||||
/*
|
||||
fn maybe_with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||
where
|
||||
Func: FnOnce(&(dyn wasmer_runtime::LikeNamespace + Send)) -> Option<InnerRet>,
|
||||
InnerRet: Sized;*/
|
||||
}
|
||||
|
||||
pub trait WasiImplementation<WB: WasmBackend> {
|
||||
@ -112,6 +105,8 @@ pub trait WasiImplementation<WB: WasmBackend> {
|
||||
preopened_files: Vec<PathBuf>,
|
||||
mapped_dirs: Vec<(String, PathBuf)>,
|
||||
) -> Result<<WB as WasmBackend>::IO, String>;
|
||||
|
||||
fn get_wasi_state(instance: &mut <WB as WasmBackend>::I) -> &wasmer_wasi::state::WasiState;
|
||||
}
|
||||
|
||||
pub trait MemoryExport {}
|
||||
@ -120,17 +115,15 @@ pub trait FunctionExport {}
|
||||
|
||||
pub trait Memory<WB: WasmBackend> {
|
||||
fn new(export: <WB as WasmBackend>::MemoryExport) -> Self;
|
||||
fn view_from_ctx(
|
||||
ctx: &wasmer_runtime::Ctx,
|
||||
memory_index: u32,
|
||||
) -> <WB as WasmBackend>::WITMemoryView;
|
||||
|
||||
fn size(&self) -> usize;
|
||||
}
|
||||
|
||||
pub trait DynamicFunc<'a> {
|
||||
fn new<F>(sig: std::sync::Arc<FuncSig>, func: F) -> Self
|
||||
pub trait DynamicFunc<'a, WB: WasmBackend> {
|
||||
fn new<'c, F>(sig: std::sync::Arc<FuncSig>, func: F) -> Self
|
||||
where
|
||||
F: Fn(
|
||||
&mut wasmer_core::vm::Ctx,
|
||||
&mut <WB as WasmBackend>::ExportContext,
|
||||
&[wasmer_core::types::Value],
|
||||
) -> Vec<wasmer_core::types::Value>
|
||||
+ 'static;
|
||||
@ -143,3 +136,15 @@ pub trait Namespace<WB: WasmBackend>: LikeNamespace<WB> {
|
||||
}
|
||||
|
||||
pub trait LikeNamespace<WB: WasmBackend> {}
|
||||
|
||||
pub trait ExportContext<WB: WasmBackend> {
|
||||
fn memory(&self, memory_index: u32) -> <WB as WasmBackend>::WITMemory;
|
||||
|
||||
unsafe fn get_export_func_by_name<'a, Args, Rets>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
) -> Result<wasmer_runtime::Func<'a, Args, Rets>, wasmer_runtime::error::ResolveError>
|
||||
where
|
||||
Args: wasmer_core::typed_func::WasmTypeList,
|
||||
Rets: wasmer_core::typed_func::WasmTypeList;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::marker::PhantomData;
|
||||
//use std::marker::PhantomData;
|
||||
use marine_wasm_backend_traits::{
|
||||
DynamicFunc, Export, LikeNamespace, Memory, Namespace, Value, WasmBackend,
|
||||
DynamicFunc, Export, ExportContext, LikeNamespace, Memory, Namespace, Value, WasmBackend,
|
||||
};
|
||||
use marine_wasm_backend_traits::WasmBackendResult;
|
||||
use marine_wasm_backend_traits::WasmBackendError;
|
||||
@ -15,9 +15,14 @@ use marine_wasm_backend_traits::WasiImplementation;
|
||||
use std::path::PathBuf;
|
||||
use std::slice::Windows;
|
||||
use std::sync::Arc;
|
||||
use wasmer_core::backend::SigRegistry;
|
||||
use wasmer_core::error::ResolveError;
|
||||
use wasmer_core::fault::raw::longjmp;
|
||||
use wasmer_core::prelude::vm::Ctx;
|
||||
use wasmer_core::types::FuncSig;
|
||||
use wasmer_core::Func;
|
||||
use wasmer_core::module::ExportIndex;
|
||||
//use wasmer_core::prelude::vm::Ctx;
|
||||
use wasmer_core::types::{FuncSig, LocalOrImport};
|
||||
use wasmer_wasi::state::WasiState;
|
||||
|
||||
mod memory_access;
|
||||
mod memory;
|
||||
@ -32,7 +37,7 @@ pub struct WasmerBackend /*<'a>*/ {
|
||||
// _data: &'a PhantomData<i32>,
|
||||
}
|
||||
|
||||
impl<'b> WasmBackend for WasmerBackend /*<'b>*/ {
|
||||
impl WasmBackend for WasmerBackend /*<'b>*/ {
|
||||
type Exports = WasmerInstance;
|
||||
type MemoryExport = WasmerMemoryExport;
|
||||
type FunctionExport = WasmerFunctionExport;
|
||||
@ -46,6 +51,7 @@ impl<'b> WasmBackend for WasmerBackend /*<'b>*/ {
|
||||
type Wasi = WasmerWasiImplementation;
|
||||
type DynamicFunc = WasmerDynamicFunc;
|
||||
type Namespace = WasmerNamespace;
|
||||
type ExportContext = WasmerExportContext<'static>;
|
||||
|
||||
fn compile(wasm: &[u8]) -> WasmBackendResult<WasmerModule> {
|
||||
wasmer_runtime::compile(wasm)
|
||||
@ -96,11 +102,8 @@ impl Instance<WasmerBackend> for WasmerInstance {
|
||||
&self.import_object
|
||||
}
|
||||
|
||||
fn context(&self) -> &wasmer_core::vm::Ctx {
|
||||
self.instance.context()
|
||||
}
|
||||
fn context_mut(&mut self) -> &mut wasmer_core::vm::Ctx {
|
||||
self.instance.context_mut()
|
||||
fn memory(&self, memory_index: u32) -> <WasmerBackend as WasmBackend>::WITMemory {
|
||||
WITMemory(self.instance.context().memory(memory_index).clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,6 +223,10 @@ impl WasiImplementation<WasmerBackend> for WasmerWasiImplementation {
|
||||
)
|
||||
.map(|import_object| WasmerImportObject { import_object })
|
||||
}
|
||||
|
||||
fn get_wasi_state(instance: &mut <WasmerBackend as WasmBackend>::I) -> &WasiState {
|
||||
unsafe { wasmer_wasi::state::get_wasi_state(instance.instance.context_mut()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Exports<WasmerBackend> for WasmerInstance {
|
||||
@ -272,7 +279,7 @@ impl Memory<WasmerBackend> for WITMemory {
|
||||
fn new(export: WasmerMemoryExport) -> Self {
|
||||
WITMemory(export.memory)
|
||||
}
|
||||
|
||||
/*
|
||||
fn view_from_ctx(ctx: &Ctx, memory_index: u32) -> WITMemoryView<'static> {
|
||||
let memory = unsafe {
|
||||
std::mem::transmute::<&'_ wasmer_runtime::Memory, &'static wasmer_runtime::Memory>(
|
||||
@ -281,6 +288,9 @@ impl Memory<WasmerBackend> for WITMemory {
|
||||
};
|
||||
|
||||
WITMemoryView(memory.view::<u8>())
|
||||
}*/
|
||||
fn size(&self) -> usize {
|
||||
self.0.size().bytes().0
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,13 +298,29 @@ pub struct WasmerDynamicFunc {
|
||||
func: wasmer_core::typed_func::DynamicFunc<'static>,
|
||||
}
|
||||
|
||||
impl<'a> DynamicFunc<'a> for WasmerDynamicFunc {
|
||||
impl<'a> DynamicFunc<'a, WasmerBackend> for WasmerDynamicFunc {
|
||||
fn new<F>(sig: Arc<FuncSig>, func: F) -> Self
|
||||
where
|
||||
F: Fn(&mut Ctx, &[wasmer_core::prelude::Value]) -> Vec<wasmer_core::prelude::Value>
|
||||
F: Fn(
|
||||
&mut WasmerExportContext<'static>,
|
||||
&[wasmer_core::prelude::Value],
|
||||
) -> Vec<wasmer_core::prelude::Value>
|
||||
+ 'static,
|
||||
{
|
||||
let func = wasmer_core::typed_func::DynamicFunc::new(sig, func);
|
||||
let func = wasmer_core::typed_func::DynamicFunc::new(
|
||||
sig,
|
||||
move |ctx: &mut wasmer_core::vm::Ctx, args: &[wasmer_core::prelude::Value]| unsafe {
|
||||
let mut ctx = WasmerExportContext {
|
||||
ctx: std::mem::transmute::<
|
||||
&'_ mut wasmer_core::vm::Ctx,
|
||||
&'static mut wasmer_core::vm::Ctx,
|
||||
>(ctx),
|
||||
};
|
||||
|
||||
func(&mut ctx, args)
|
||||
},
|
||||
);
|
||||
|
||||
Self { func }
|
||||
}
|
||||
}
|
||||
@ -322,3 +348,83 @@ struct WasmerLikeNamespace {
|
||||
}
|
||||
|
||||
impl LikeNamespace<WasmerBackend> for WasmerLikeNamespace {}
|
||||
|
||||
pub struct WasmerExportContext<'c> {
|
||||
ctx: &'c mut wasmer_core::vm::Ctx,
|
||||
}
|
||||
|
||||
impl<'c> ExportContext<WasmerBackend> for WasmerExportContext<'c> {
|
||||
fn memory(&self, memory_index: u32) -> <WasmerBackend as WasmBackend>::WITMemory {
|
||||
WITMemory(self.ctx.memory(memory_index).clone())
|
||||
}
|
||||
|
||||
unsafe fn get_export_func_by_name<'a, Args, Rets>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
) -> Result<Func<'a, Args, Rets>, ResolveError>
|
||||
where
|
||||
Args: wasmer_core::typed_func::WasmTypeList,
|
||||
Rets: wasmer_core::typed_func::WasmTypeList,
|
||||
{
|
||||
let ctx = &mut self.ctx;
|
||||
let module_inner = &(*ctx.module);
|
||||
|
||||
let export_index =
|
||||
module_inner
|
||||
.info
|
||||
.exports
|
||||
.get(name)
|
||||
.ok_or_else(|| ResolveError::ExportNotFound {
|
||||
name: name.to_string(),
|
||||
})?;
|
||||
|
||||
let export_func_index = match export_index {
|
||||
ExportIndex::Func(func_index) => func_index,
|
||||
_ => {
|
||||
return Err(ResolveError::ExportWrongType {
|
||||
name: name.to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let export_func_signature_idx = *module_inner
|
||||
.info
|
||||
.func_assoc
|
||||
.get(*export_func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
|
||||
let export_func_signature = &module_inner.info.signatures[export_func_signature_idx];
|
||||
let export_func_signature_ref = SigRegistry.lookup_signature_ref(export_func_signature);
|
||||
|
||||
if export_func_signature_ref.params() != Args::types()
|
||||
|| export_func_signature_ref.returns() != Rets::types()
|
||||
{
|
||||
return Err(ResolveError::Signature {
|
||||
expected: (*export_func_signature).clone(),
|
||||
found: Args::types().to_vec(),
|
||||
});
|
||||
}
|
||||
|
||||
let func_wasm_inner = module_inner
|
||||
.runnable_module
|
||||
.get_trampoline(&module_inner.info, export_func_signature_idx)
|
||||
.unwrap();
|
||||
|
||||
let export_func_ptr = match export_func_index.local_or_import(&module_inner.info) {
|
||||
LocalOrImport::Local(local_func_index) => module_inner
|
||||
.runnable_module
|
||||
.get_func(&module_inner.info, local_func_index)
|
||||
.unwrap(),
|
||||
_ => {
|
||||
return Err(ResolveError::ExportNotFound {
|
||||
name: name.to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let typed_func: Func<'_, Args, Rets, wasmer_core::typed_func::Wasm> =
|
||||
Func::from_raw_parts(func_wasm_inner, export_func_ptr, None, (*ctx) as _);
|
||||
|
||||
Ok(typed_func)
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use marine_wasm_backend_traits::ImportObject;
|
||||
|
||||
use wasmer_wasi::WasiVersion;
|
||||
//use wasmer_runtime::ImportObject;
|
||||
use wasmer_core::vm::Ctx;
|
||||
//use wasmer_core::vm::Ctx;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::collections::HashMap;
|
||||
@ -32,11 +32,12 @@ use std::collections::HashSet;
|
||||
// 65536*1600 ~ 100 Mb (Wasm page size is 64 Kb)
|
||||
const DEFAULT_HEAP_PAGES_COUNT: u32 = 1600;
|
||||
|
||||
pub type HostExportedFunc = Box<dyn Fn(&mut Ctx, Vec<IValue>) -> Option<IValue> + 'static>;
|
||||
pub type HostExportedFunc<WB> =
|
||||
Box<dyn Fn(&mut <WB as WasmBackend>::ExportContext, Vec<IValue>) -> Option<IValue> + 'static>;
|
||||
|
||||
pub struct HostImportDescriptor {
|
||||
pub struct HostImportDescriptor<WB: WasmBackend> {
|
||||
/// This closure will be invoked for corresponding import.
|
||||
pub host_exported_func: HostExportedFunc,
|
||||
pub host_exported_func: HostExportedFunc<WB>,
|
||||
|
||||
/// Type of the closure arguments.
|
||||
pub argument_types: Vec<IType>,
|
||||
@ -58,7 +59,7 @@ pub struct MModuleConfig<WB: WasmBackend> {
|
||||
pub raw_imports: <WB as WasmBackend>::IO,
|
||||
|
||||
/// Imports from the host side that will be used in module instantiation process.
|
||||
pub host_imports: HashMap<String, HostImportDescriptor>,
|
||||
pub host_imports: HashMap<String, HostImportDescriptor<WB>>,
|
||||
|
||||
/// Desired WASI version.
|
||||
pub wasi_version: WasiVersion,
|
||||
|
@ -29,22 +29,23 @@ use crate::HostImportDescriptor;
|
||||
//use crate::module::wit_prelude::WITMemoryView;
|
||||
|
||||
//use wasmer_core::Func;
|
||||
use wasmer_core::vm::Ctx;
|
||||
//use wasmer_core::vm::Ctx;
|
||||
//use wasmer_core::typed_func::DynamicFunc;
|
||||
use wasmer_core::types::Value as WValue;
|
||||
use wasmer_core::types::FuncSig;
|
||||
use it_lilo::lifter::ILifter;
|
||||
use it_lilo::lowerer::ILowerer;
|
||||
use it_memory_traits::Memory as ITMemory;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use marine_wasm_backend_traits::WasmBackend;
|
||||
use marine_wasm_backend_traits::Memory;
|
||||
use marine_wasm_backend_traits::DynamicFunc;
|
||||
use marine_wasm_backend_traits::ExportContext;
|
||||
|
||||
pub(crate) fn create_host_import_func<WB: WasmBackend>(
|
||||
descriptor: HostImportDescriptor,
|
||||
descriptor: HostImportDescriptor<WB>,
|
||||
record_types: Rc<MRecordTypes>,
|
||||
) -> <WB as WasmBackend>::DynamicFunc {
|
||||
let allocate_func: AllocateFunc = Box::new(RefCell::new(None));
|
||||
@ -66,82 +67,98 @@ pub(crate) fn create_host_import_func<WB: WasmBackend>(
|
||||
let raw_args = itypes_args_to_wtypes(&argument_types);
|
||||
let raw_output = itypes_output_to_wtypes(&output_type_to_types(output_type));
|
||||
|
||||
let func = move |ctx: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
|
||||
let result = {
|
||||
let memory_index = 0;
|
||||
//let memory = ctx.memory(memory_index);
|
||||
//let memory_view = WITMemoryView(memory.view::<u8>());
|
||||
let memory_view = <WB as WasmBackend>::WITMemory::view_from_ctx(ctx, memory_index);
|
||||
let li_helper = LiHelper::new(record_types.clone());
|
||||
let lifter = ILifter::new(memory_view, &li_helper);
|
||||
let func =
|
||||
move |ctx: &mut <WB as WasmBackend>::ExportContext, inputs: &[WValue]| -> Vec<WValue> {
|
||||
let result = {
|
||||
let memory_index = 0;
|
||||
let memory_view = ctx.memory(memory_index).view();
|
||||
let li_helper = LiHelper::new(record_types.clone());
|
||||
let lifter = ILifter::new(memory_view, &li_helper);
|
||||
|
||||
match wvalues_to_ivalues(&lifter, inputs, &argument_types) {
|
||||
Ok(ivalues) => host_exported_func(ctx, ivalues),
|
||||
Err(e) => {
|
||||
log::error!("error occurred while lifting values in host import: {}", e);
|
||||
error_handler
|
||||
.as_ref()
|
||||
.map_or_else(|| default_error_handler(&e), |h| h(&e))
|
||||
match wvalues_to_ivalues(&lifter, inputs, &argument_types) {
|
||||
Ok(ivalues) => host_exported_func(ctx, ivalues),
|
||||
Err(e) => {
|
||||
log::error!("error occurred while lifting values in host import: {}", e);
|
||||
error_handler
|
||||
.as_ref()
|
||||
.map_or_else(|| default_error_handler(&e), |h| h(&e))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let ctx = ctx;
|
||||
init_wasm_func_once!(allocate_func, ctx, (i32, i32), i32, ALLOCATE_FUNC_NAME, 2);
|
||||
/*if allocate_func.borrow().is_none() {
|
||||
let raw_func = match unsafe {
|
||||
ctx.get_export_func_by_name::<(i32, i32), i32>(ALLOCATE_FUNC_NAME)
|
||||
} {
|
||||
Ok(func) => func,
|
||||
Err(_) => return vec![WValue::I32(2)],
|
||||
};
|
||||
|
||||
unsafe {
|
||||
// assumed that this function will be used only in the context of closure
|
||||
// linked to a corresponding Wasm import, so it is safe to make is static
|
||||
// because all Wasm imports live in the Wasmer instances, which
|
||||
// is itself static (i.e., lives until the end of the program)
|
||||
let raw_func = std::mem::transmute::<Func<'_, _, _>, Func<'static, _, _>>(raw_func);
|
||||
|
||||
*allocate_func.borrow_mut() = Some(raw_func);
|
||||
}
|
||||
}*/
|
||||
|
||||
let memory_index = 0;
|
||||
let memory_view = ctx.memory(memory_index).view();
|
||||
let lo_helper = LoHelper::new(&allocate_func);
|
||||
let t = ILowerer::new(memory_view, &lo_helper)
|
||||
.map_err(HostImportError::LowererError)
|
||||
.and_then(|lowerer| ivalue_to_wvalues(&lowerer, result));
|
||||
|
||||
let wvalues = match t {
|
||||
Ok(wvalues) => wvalues,
|
||||
Err(e) => {
|
||||
log::error!("host closure failed: {}", e);
|
||||
|
||||
// returns 0 to a Wasm module in case of errors
|
||||
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 4);
|
||||
init_wasm_func_once!(set_result_size_func, ctx, i32, (), SET_SIZE_FUNC_NAME, 4);
|
||||
|
||||
call_wasm_func!(set_result_ptr_func, 0);
|
||||
call_wasm_func!(set_result_size_func, 0);
|
||||
return vec![WValue::I32(0)];
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: refactor this when multi-value is supported
|
||||
match wvalues.len() {
|
||||
// strings and arrays are passed back to the Wasm module by pointer and size
|
||||
2 => {
|
||||
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 4);
|
||||
init_wasm_func_once!(set_result_size_func, ctx, i32, (), SET_SIZE_FUNC_NAME, 4);
|
||||
|
||||
call_wasm_func!(set_result_ptr_func, wvalues[0].to_u128() as _);
|
||||
call_wasm_func!(set_result_size_func, wvalues[1].to_u128() as _);
|
||||
vec![]
|
||||
}
|
||||
|
||||
// records and primitive types are passed to the Wasm module by pointer
|
||||
// and value on the stack
|
||||
1 => {
|
||||
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 3);
|
||||
|
||||
call_wasm_func!(set_result_ptr_func, wvalues[0].to_u128() as _);
|
||||
vec![wvalues[0].clone()]
|
||||
}
|
||||
|
||||
// when None is passed
|
||||
0 => vec![],
|
||||
|
||||
// at now while multi-values aren't supported ivalue_to_wvalues returns only Vec with
|
||||
// 0, 1, 2 values
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
};
|
||||
|
||||
init_wasm_func_once!(allocate_func, ctx, (i32, i32), i32, ALLOCATE_FUNC_NAME, 2);
|
||||
|
||||
let memory_index = 0;
|
||||
//let memory = ctx.memory(memory_index);
|
||||
//let memory_view = WITMemoryView(memory.view::<u8>());
|
||||
let memory_view = <WB as WasmBackend>::WITMemory::view_from_ctx(ctx, memory_index);
|
||||
let lo_helper = LoHelper::new(&allocate_func);
|
||||
let t = ILowerer::new(memory_view, &lo_helper)
|
||||
.map_err(HostImportError::LowererError)
|
||||
.and_then(|lowerer| ivalue_to_wvalues(&lowerer, result));
|
||||
|
||||
let wvalues = match t {
|
||||
Ok(wvalues) => wvalues,
|
||||
Err(e) => {
|
||||
log::error!("host closure failed: {}", e);
|
||||
|
||||
// returns 0 to a Wasm module in case of errors
|
||||
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 4);
|
||||
init_wasm_func_once!(set_result_size_func, ctx, i32, (), SET_SIZE_FUNC_NAME, 4);
|
||||
|
||||
call_wasm_func!(set_result_ptr_func, 0);
|
||||
call_wasm_func!(set_result_size_func, 0);
|
||||
return vec![WValue::I32(0)];
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: refactor this when multi-value is supported
|
||||
match wvalues.len() {
|
||||
// strings and arrays are passed back to the Wasm module by pointer and size
|
||||
2 => {
|
||||
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 4);
|
||||
init_wasm_func_once!(set_result_size_func, ctx, i32, (), SET_SIZE_FUNC_NAME, 4);
|
||||
|
||||
call_wasm_func!(set_result_ptr_func, wvalues[0].to_u128() as _);
|
||||
call_wasm_func!(set_result_size_func, wvalues[1].to_u128() as _);
|
||||
vec![]
|
||||
}
|
||||
|
||||
// records and primitive types are passed to the Wasm module by pointer
|
||||
// and value on the stack
|
||||
1 => {
|
||||
init_wasm_func_once!(set_result_ptr_func, ctx, i32, (), SET_PTR_FUNC_NAME, 3);
|
||||
|
||||
call_wasm_func!(set_result_ptr_func, wvalues[0].to_u128() as _);
|
||||
vec![wvalues[0].clone()]
|
||||
}
|
||||
|
||||
// when None is passed
|
||||
0 => vec![],
|
||||
|
||||
// at now while multi-values aren't supported ivalue_to_wvalues returns only Vec with
|
||||
// 0, 1, 2 values
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
};
|
||||
|
||||
<WB as WasmBackend>::DynamicFunc::new(
|
||||
std::sync::Arc::new(FuncSig::new(raw_args, raw_output)),
|
||||
func,
|
||||
|
@ -17,6 +17,7 @@
|
||||
use super::WType;
|
||||
use crate::IType;
|
||||
|
||||
/*
|
||||
use wasmer_core::backend::SigRegistry;
|
||||
use wasmer_core::module::ExportIndex;
|
||||
use wasmer_core::vm::Ctx;
|
||||
@ -24,7 +25,9 @@ use wasmer_core::typed_func::WasmTypeList;
|
||||
use wasmer_runtime::Func;
|
||||
use wasmer_runtime::error::ResolveError;
|
||||
use wasmer_runtime::types::LocalOrImport;
|
||||
*/
|
||||
|
||||
/*
|
||||
// based on Wasmer: https://github.com/wasmerio/wasmer/blob/081f6250e69b98b9f95a8f62ad6d8386534f3279/lib/runtime-core/src/instance.rs#L863
|
||||
/// Extract export function from Wasmer instance by name.
|
||||
pub(super) unsafe fn get_export_func_by_name<'a, Args, Rets>(
|
||||
@ -95,7 +98,7 @@ where
|
||||
|
||||
Ok(typed_func)
|
||||
}
|
||||
|
||||
*/
|
||||
pub(super) fn itypes_args_to_wtypes(itypes: &[IType]) -> Vec<WType> {
|
||||
itypes
|
||||
.iter()
|
||||
@ -127,9 +130,8 @@ pub(super) fn itypes_output_to_wtypes(itypes: &[IType]) -> Vec<WType> {
|
||||
macro_rules! init_wasm_func_once {
|
||||
($func:ident, $ctx:ident, $args:ty, $rets:ty, $func_name:ident, $ret_error_code: expr) => {
|
||||
if $func.borrow().is_none() {
|
||||
let raw_func = match unsafe {
|
||||
super::utils::get_export_func_by_name::<$args, $rets>($ctx, $func_name)
|
||||
} {
|
||||
let raw_func = match unsafe { $ctx.get_export_func_by_name::<$args, $rets>($func_name) }
|
||||
{
|
||||
Ok(func) => func,
|
||||
Err(_) => return vec![WValue::I32($ret_error_code)],
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::borrow::BorrowMut;
|
||||
use super::wit_prelude::*;
|
||||
use super::MFunctionSignature;
|
||||
use super::MRecordTypes;
|
||||
@ -29,6 +30,7 @@ use marine_wasm_backend_traits::WasiImplementation;
|
||||
use marine_wasm_backend_traits::Exports;
|
||||
use marine_wasm_backend_traits::Namespace;
|
||||
use marine_wasm_backend_traits::DynamicFunc;
|
||||
use marine_wasm_backend_traits::Memory;
|
||||
|
||||
use marine_it_interfaces::MITInterfaces;
|
||||
use marine_it_parser::extract_it_from_module;
|
||||
@ -196,7 +198,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
}
|
||||
|
||||
pub(crate) fn get_wasi_state(&mut self) -> &wasmer_wasi::state::WasiState {
|
||||
unsafe { wasmer_wasi::state::get_wasi_state(self.wasmer_instance.context_mut()) }
|
||||
<WB as WasmBackend>::Wasi::get_wasi_state(self.wasmer_instance.borrow_mut())
|
||||
}
|
||||
|
||||
/// Returns heap size that this module consumes in bytes.
|
||||
@ -204,8 +206,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
// Wasmer 0.17.1 supports only one memory
|
||||
const MEMORY_INDEX: u32 = 0;
|
||||
|
||||
let pages = self.wasmer_instance.context().memory(MEMORY_INDEX).size();
|
||||
pages.bytes().0
|
||||
self.wasmer_instance.memory(MEMORY_INDEX).size()
|
||||
}
|
||||
|
||||
// TODO: change the cloning Callable behaviour after changes of Wasmer API
|
||||
@ -311,7 +312,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
) -> MResult<<WB as WasmBackend>::IO> {
|
||||
use marine_it_interfaces::ITAstType;
|
||||
//use wasmer_core::typed_func::DynamicFunc;
|
||||
use wasmer_core::vm::Ctx;
|
||||
//use wasmer_core::vm::Ctx;
|
||||
|
||||
// returns function that will be called from imports of Wasmer module
|
||||
fn dyn_func_from_raw_import<'a, 'b, F, WB, I1, I2>(
|
||||
@ -320,7 +321,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
raw_import: F,
|
||||
) -> <WB as WasmBackend>::DynamicFunc
|
||||
where
|
||||
F: Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static,
|
||||
F: Fn(&mut <WB as WasmBackend>::ExportContext, &[WValue]) -> Vec<WValue> + 'static,
|
||||
WB: WasmBackend,
|
||||
I1: Iterator<Item = &'a IType>,
|
||||
I2: Iterator<Item = &'b IType>,
|
||||
@ -342,8 +343,9 @@ impl<WB: WasmBackend> MModule<WB> {
|
||||
interpreter: ITInterpreter<WB>,
|
||||
import_namespace: String,
|
||||
import_name: String,
|
||||
) -> impl Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static {
|
||||
move |_: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
|
||||
) -> impl Fn(&mut <WB as WasmBackend>::ExportContext, &[WValue]) -> Vec<WValue> + 'static
|
||||
{
|
||||
move |_: &mut <WB as WasmBackend>::ExportContext, inputs: &[WValue]| -> Vec<WValue> {
|
||||
use wasmer_it::interpreter::stack::Stackable;
|
||||
|
||||
use super::type_converters::wval_to_ival;
|
||||
|
Loading…
x
Reference in New Issue
Block a user