mirror of
https://github.com/fluencelabs/marine.git
synced 2025-03-15 14:00:50 +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 std::path::PathBuf;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wasmer_core::types::FuncSig;
|
use wasmer_core::types::FuncSig;
|
||||||
use it_memory_traits::{SequentialMemoryView, SequentialReader, SequentialWriter};
|
use it_memory_traits::{SequentialMemoryView};
|
||||||
|
|
||||||
pub struct Value {}
|
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 WITMemory: Memory<Self> + it_memory_traits::Memory<Self::WITMemoryView> + Clone + 'static;
|
||||||
//type SR: SequentialReader;
|
//type SR: SequentialReader;
|
||||||
//type SW: SequentialWriter;
|
//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 WITMemoryView: for<'a> SequentialMemoryView<'a /* SR = Self::SR, SW = Self::SW*/> + 'static;
|
||||||
type FunctionExport: FunctionExport;
|
type FunctionExport: FunctionExport;
|
||||||
type M: Module<Self>;
|
type M: Module<Self>;
|
||||||
type I: Instance<Self>;
|
type I: Instance<Self>;
|
||||||
type Wasi: WasiImplementation<Self>;
|
type Wasi: WasiImplementation<Self>;
|
||||||
type Namespace: Namespace<Self>;
|
type Namespace: Namespace<Self>;
|
||||||
|
type ExportContext: ExportContext<Self>;
|
||||||
|
|
||||||
fn compile(wasm: &[u8]) -> WasmBackendResult<Self::M>;
|
fn compile(wasm: &[u8]) -> WasmBackendResult<Self::M>;
|
||||||
}
|
}
|
||||||
@ -56,10 +57,7 @@ pub trait Instance<WB: WasmBackend> {
|
|||||||
>;
|
>;
|
||||||
fn exports(&self) -> &<WB as WasmBackend>::Exports;
|
fn exports(&self) -> &<WB as WasmBackend>::Exports;
|
||||||
fn import_object(&self) -> &<WB as WasmBackend>::IO;
|
fn import_object(&self) -> &<WB as WasmBackend>::IO;
|
||||||
|
fn memory(&self, memory_index: u32) -> <WB as WasmBackend>::WITMemory;
|
||||||
// maybe hide them inside impl
|
|
||||||
fn context(&self) -> &wasmer_core::vm::Ctx;
|
|
||||||
fn context_mut(&mut self) -> &mut wasmer_core::vm::Ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Exports<WB: WasmBackend> {
|
pub trait Exports<WB: WasmBackend> {
|
||||||
@ -97,11 +95,6 @@ pub trait ImportObject<WB: WasmBackend>:
|
|||||||
fn get_memory_env(
|
fn get_memory_env(
|
||||||
&self,
|
&self,
|
||||||
) -> Option<Export<<WB as WasmBackend>::MemoryExport, <WB as WasmBackend>::FunctionExport>>;
|
) -> 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> {
|
pub trait WasiImplementation<WB: WasmBackend> {
|
||||||
@ -112,6 +105,8 @@ pub trait WasiImplementation<WB: WasmBackend> {
|
|||||||
preopened_files: Vec<PathBuf>,
|
preopened_files: Vec<PathBuf>,
|
||||||
mapped_dirs: Vec<(String, PathBuf)>,
|
mapped_dirs: Vec<(String, PathBuf)>,
|
||||||
) -> Result<<WB as WasmBackend>::IO, String>;
|
) -> Result<<WB as WasmBackend>::IO, String>;
|
||||||
|
|
||||||
|
fn get_wasi_state(instance: &mut <WB as WasmBackend>::I) -> &wasmer_wasi::state::WasiState;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MemoryExport {}
|
pub trait MemoryExport {}
|
||||||
@ -120,17 +115,15 @@ pub trait FunctionExport {}
|
|||||||
|
|
||||||
pub trait Memory<WB: WasmBackend> {
|
pub trait Memory<WB: WasmBackend> {
|
||||||
fn new(export: <WB as WasmBackend>::MemoryExport) -> Self;
|
fn new(export: <WB as WasmBackend>::MemoryExport) -> Self;
|
||||||
fn view_from_ctx(
|
|
||||||
ctx: &wasmer_runtime::Ctx,
|
fn size(&self) -> usize;
|
||||||
memory_index: u32,
|
|
||||||
) -> <WB as WasmBackend>::WITMemoryView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DynamicFunc<'a> {
|
pub trait DynamicFunc<'a, WB: WasmBackend> {
|
||||||
fn new<F>(sig: std::sync::Arc<FuncSig>, func: F) -> Self
|
fn new<'c, F>(sig: std::sync::Arc<FuncSig>, func: F) -> Self
|
||||||
where
|
where
|
||||||
F: Fn(
|
F: Fn(
|
||||||
&mut wasmer_core::vm::Ctx,
|
&mut <WB as WasmBackend>::ExportContext,
|
||||||
&[wasmer_core::types::Value],
|
&[wasmer_core::types::Value],
|
||||||
) -> Vec<wasmer_core::types::Value>
|
) -> Vec<wasmer_core::types::Value>
|
||||||
+ 'static;
|
+ 'static;
|
||||||
@ -143,3 +136,15 @@ pub trait Namespace<WB: WasmBackend>: LikeNamespace<WB> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait LikeNamespace<WB: WasmBackend> {}
|
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::{
|
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::WasmBackendResult;
|
||||||
use marine_wasm_backend_traits::WasmBackendError;
|
use marine_wasm_backend_traits::WasmBackendError;
|
||||||
@ -15,9 +15,14 @@ use marine_wasm_backend_traits::WasiImplementation;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::slice::Windows;
|
use std::slice::Windows;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use wasmer_core::backend::SigRegistry;
|
||||||
|
use wasmer_core::error::ResolveError;
|
||||||
use wasmer_core::fault::raw::longjmp;
|
use wasmer_core::fault::raw::longjmp;
|
||||||
use wasmer_core::prelude::vm::Ctx;
|
use wasmer_core::Func;
|
||||||
use wasmer_core::types::FuncSig;
|
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_access;
|
||||||
mod memory;
|
mod memory;
|
||||||
@ -32,7 +37,7 @@ pub struct WasmerBackend /*<'a>*/ {
|
|||||||
// _data: &'a PhantomData<i32>,
|
// _data: &'a PhantomData<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> WasmBackend for WasmerBackend /*<'b>*/ {
|
impl WasmBackend for WasmerBackend /*<'b>*/ {
|
||||||
type Exports = WasmerInstance;
|
type Exports = WasmerInstance;
|
||||||
type MemoryExport = WasmerMemoryExport;
|
type MemoryExport = WasmerMemoryExport;
|
||||||
type FunctionExport = WasmerFunctionExport;
|
type FunctionExport = WasmerFunctionExport;
|
||||||
@ -46,6 +51,7 @@ impl<'b> WasmBackend for WasmerBackend /*<'b>*/ {
|
|||||||
type Wasi = WasmerWasiImplementation;
|
type Wasi = WasmerWasiImplementation;
|
||||||
type DynamicFunc = WasmerDynamicFunc;
|
type DynamicFunc = WasmerDynamicFunc;
|
||||||
type Namespace = WasmerNamespace;
|
type Namespace = WasmerNamespace;
|
||||||
|
type ExportContext = WasmerExportContext<'static>;
|
||||||
|
|
||||||
fn compile(wasm: &[u8]) -> WasmBackendResult<WasmerModule> {
|
fn compile(wasm: &[u8]) -> WasmBackendResult<WasmerModule> {
|
||||||
wasmer_runtime::compile(wasm)
|
wasmer_runtime::compile(wasm)
|
||||||
@ -96,11 +102,8 @@ impl Instance<WasmerBackend> for WasmerInstance {
|
|||||||
&self.import_object
|
&self.import_object
|
||||||
}
|
}
|
||||||
|
|
||||||
fn context(&self) -> &wasmer_core::vm::Ctx {
|
fn memory(&self, memory_index: u32) -> <WasmerBackend as WasmBackend>::WITMemory {
|
||||||
self.instance.context()
|
WITMemory(self.instance.context().memory(memory_index).clone())
|
||||||
}
|
|
||||||
fn context_mut(&mut self) -> &mut wasmer_core::vm::Ctx {
|
|
||||||
self.instance.context_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +223,10 @@ impl WasiImplementation<WasmerBackend> for WasmerWasiImplementation {
|
|||||||
)
|
)
|
||||||
.map(|import_object| WasmerImportObject { import_object })
|
.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 {
|
impl Exports<WasmerBackend> for WasmerInstance {
|
||||||
@ -272,7 +279,7 @@ impl Memory<WasmerBackend> for WITMemory {
|
|||||||
fn new(export: WasmerMemoryExport) -> Self {
|
fn new(export: WasmerMemoryExport) -> Self {
|
||||||
WITMemory(export.memory)
|
WITMemory(export.memory)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
fn view_from_ctx(ctx: &Ctx, memory_index: u32) -> WITMemoryView<'static> {
|
fn view_from_ctx(ctx: &Ctx, memory_index: u32) -> WITMemoryView<'static> {
|
||||||
let memory = unsafe {
|
let memory = unsafe {
|
||||||
std::mem::transmute::<&'_ wasmer_runtime::Memory, &'static wasmer_runtime::Memory>(
|
std::mem::transmute::<&'_ wasmer_runtime::Memory, &'static wasmer_runtime::Memory>(
|
||||||
@ -281,6 +288,9 @@ impl Memory<WasmerBackend> for WITMemory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
WITMemoryView(memory.view::<u8>())
|
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>,
|
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
|
fn new<F>(sig: Arc<FuncSig>, func: F) -> Self
|
||||||
where
|
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,
|
+ '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 }
|
Self { func }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,3 +348,83 @@ struct WasmerLikeNamespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LikeNamespace<WasmerBackend> for 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_wasi::WasiVersion;
|
||||||
//use wasmer_runtime::ImportObject;
|
//use wasmer_runtime::ImportObject;
|
||||||
use wasmer_core::vm::Ctx;
|
//use wasmer_core::vm::Ctx;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -32,11 +32,12 @@ use std::collections::HashSet;
|
|||||||
// 65536*1600 ~ 100 Mb (Wasm page size is 64 Kb)
|
// 65536*1600 ~ 100 Mb (Wasm page size is 64 Kb)
|
||||||
const DEFAULT_HEAP_PAGES_COUNT: u32 = 1600;
|
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.
|
/// This closure will be invoked for corresponding import.
|
||||||
pub host_exported_func: HostExportedFunc,
|
pub host_exported_func: HostExportedFunc<WB>,
|
||||||
|
|
||||||
/// Type of the closure arguments.
|
/// Type of the closure arguments.
|
||||||
pub argument_types: Vec<IType>,
|
pub argument_types: Vec<IType>,
|
||||||
@ -58,7 +59,7 @@ pub struct MModuleConfig<WB: WasmBackend> {
|
|||||||
pub raw_imports: <WB as WasmBackend>::IO,
|
pub raw_imports: <WB as WasmBackend>::IO,
|
||||||
|
|
||||||
/// Imports from the host side that will be used in module instantiation process.
|
/// 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.
|
/// Desired WASI version.
|
||||||
pub wasi_version: WasiVersion,
|
pub wasi_version: WasiVersion,
|
||||||
|
@ -29,22 +29,23 @@ use crate::HostImportDescriptor;
|
|||||||
//use crate::module::wit_prelude::WITMemoryView;
|
//use crate::module::wit_prelude::WITMemoryView;
|
||||||
|
|
||||||
//use wasmer_core::Func;
|
//use wasmer_core::Func;
|
||||||
use wasmer_core::vm::Ctx;
|
//use wasmer_core::vm::Ctx;
|
||||||
//use wasmer_core::typed_func::DynamicFunc;
|
//use wasmer_core::typed_func::DynamicFunc;
|
||||||
use wasmer_core::types::Value as WValue;
|
use wasmer_core::types::Value as WValue;
|
||||||
use wasmer_core::types::FuncSig;
|
use wasmer_core::types::FuncSig;
|
||||||
use it_lilo::lifter::ILifter;
|
use it_lilo::lifter::ILifter;
|
||||||
use it_lilo::lowerer::ILowerer;
|
use it_lilo::lowerer::ILowerer;
|
||||||
|
use it_memory_traits::Memory as ITMemory;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use marine_wasm_backend_traits::WasmBackend;
|
use marine_wasm_backend_traits::WasmBackend;
|
||||||
use marine_wasm_backend_traits::Memory;
|
|
||||||
use marine_wasm_backend_traits::DynamicFunc;
|
use marine_wasm_backend_traits::DynamicFunc;
|
||||||
|
use marine_wasm_backend_traits::ExportContext;
|
||||||
|
|
||||||
pub(crate) fn create_host_import_func<WB: WasmBackend>(
|
pub(crate) fn create_host_import_func<WB: WasmBackend>(
|
||||||
descriptor: HostImportDescriptor,
|
descriptor: HostImportDescriptor<WB>,
|
||||||
record_types: Rc<MRecordTypes>,
|
record_types: Rc<MRecordTypes>,
|
||||||
) -> <WB as WasmBackend>::DynamicFunc {
|
) -> <WB as WasmBackend>::DynamicFunc {
|
||||||
let allocate_func: AllocateFunc = Box::new(RefCell::new(None));
|
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_args = itypes_args_to_wtypes(&argument_types);
|
||||||
let raw_output = itypes_output_to_wtypes(&output_type_to_types(output_type));
|
let raw_output = itypes_output_to_wtypes(&output_type_to_types(output_type));
|
||||||
|
|
||||||
let func = move |ctx: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
|
let func =
|
||||||
let result = {
|
move |ctx: &mut <WB as WasmBackend>::ExportContext, inputs: &[WValue]| -> Vec<WValue> {
|
||||||
let memory_index = 0;
|
let result = {
|
||||||
//let memory = ctx.memory(memory_index);
|
let memory_index = 0;
|
||||||
//let memory_view = WITMemoryView(memory.view::<u8>());
|
let memory_view = ctx.memory(memory_index).view();
|
||||||
let memory_view = <WB as WasmBackend>::WITMemory::view_from_ctx(ctx, memory_index);
|
let li_helper = LiHelper::new(record_types.clone());
|
||||||
let li_helper = LiHelper::new(record_types.clone());
|
let lifter = ILifter::new(memory_view, &li_helper);
|
||||||
let lifter = ILifter::new(memory_view, &li_helper);
|
|
||||||
|
|
||||||
match wvalues_to_ivalues(&lifter, inputs, &argument_types) {
|
match wvalues_to_ivalues(&lifter, inputs, &argument_types) {
|
||||||
Ok(ivalues) => host_exported_func(ctx, ivalues),
|
Ok(ivalues) => host_exported_func(ctx, ivalues),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("error occurred while lifting values in host import: {}", e);
|
log::error!("error occurred while lifting values in host import: {}", e);
|
||||||
error_handler
|
error_handler
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or_else(|| default_error_handler(&e), |h| h(&e))
|
.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(
|
<WB as WasmBackend>::DynamicFunc::new(
|
||||||
std::sync::Arc::new(FuncSig::new(raw_args, raw_output)),
|
std::sync::Arc::new(FuncSig::new(raw_args, raw_output)),
|
||||||
func,
|
func,
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
use super::WType;
|
use super::WType;
|
||||||
use crate::IType;
|
use crate::IType;
|
||||||
|
|
||||||
|
/*
|
||||||
use wasmer_core::backend::SigRegistry;
|
use wasmer_core::backend::SigRegistry;
|
||||||
use wasmer_core::module::ExportIndex;
|
use wasmer_core::module::ExportIndex;
|
||||||
use wasmer_core::vm::Ctx;
|
use wasmer_core::vm::Ctx;
|
||||||
@ -24,7 +25,9 @@ use wasmer_core::typed_func::WasmTypeList;
|
|||||||
use wasmer_runtime::Func;
|
use wasmer_runtime::Func;
|
||||||
use wasmer_runtime::error::ResolveError;
|
use wasmer_runtime::error::ResolveError;
|
||||||
use wasmer_runtime::types::LocalOrImport;
|
use wasmer_runtime::types::LocalOrImport;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
// based on Wasmer: https://github.com/wasmerio/wasmer/blob/081f6250e69b98b9f95a8f62ad6d8386534f3279/lib/runtime-core/src/instance.rs#L863
|
// 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.
|
/// Extract export function from Wasmer instance by name.
|
||||||
pub(super) unsafe fn get_export_func_by_name<'a, Args, Rets>(
|
pub(super) unsafe fn get_export_func_by_name<'a, Args, Rets>(
|
||||||
@ -95,7 +98,7 @@ where
|
|||||||
|
|
||||||
Ok(typed_func)
|
Ok(typed_func)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
pub(super) fn itypes_args_to_wtypes(itypes: &[IType]) -> Vec<WType> {
|
pub(super) fn itypes_args_to_wtypes(itypes: &[IType]) -> Vec<WType> {
|
||||||
itypes
|
itypes
|
||||||
.iter()
|
.iter()
|
||||||
@ -127,9 +130,8 @@ pub(super) fn itypes_output_to_wtypes(itypes: &[IType]) -> Vec<WType> {
|
|||||||
macro_rules! init_wasm_func_once {
|
macro_rules! init_wasm_func_once {
|
||||||
($func:ident, $ctx:ident, $args:ty, $rets:ty, $func_name:ident, $ret_error_code: expr) => {
|
($func:ident, $ctx:ident, $args:ty, $rets:ty, $func_name:ident, $ret_error_code: expr) => {
|
||||||
if $func.borrow().is_none() {
|
if $func.borrow().is_none() {
|
||||||
let raw_func = match unsafe {
|
let raw_func = match unsafe { $ctx.get_export_func_by_name::<$args, $rets>($func_name) }
|
||||||
super::utils::get_export_func_by_name::<$args, $rets>($ctx, $func_name)
|
{
|
||||||
} {
|
|
||||||
Ok(func) => func,
|
Ok(func) => func,
|
||||||
Err(_) => return vec![WValue::I32($ret_error_code)],
|
Err(_) => return vec![WValue::I32($ret_error_code)],
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
use super::wit_prelude::*;
|
use super::wit_prelude::*;
|
||||||
use super::MFunctionSignature;
|
use super::MFunctionSignature;
|
||||||
use super::MRecordTypes;
|
use super::MRecordTypes;
|
||||||
@ -29,6 +30,7 @@ use marine_wasm_backend_traits::WasiImplementation;
|
|||||||
use marine_wasm_backend_traits::Exports;
|
use marine_wasm_backend_traits::Exports;
|
||||||
use marine_wasm_backend_traits::Namespace;
|
use marine_wasm_backend_traits::Namespace;
|
||||||
use marine_wasm_backend_traits::DynamicFunc;
|
use marine_wasm_backend_traits::DynamicFunc;
|
||||||
|
use marine_wasm_backend_traits::Memory;
|
||||||
|
|
||||||
use marine_it_interfaces::MITInterfaces;
|
use marine_it_interfaces::MITInterfaces;
|
||||||
use marine_it_parser::extract_it_from_module;
|
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 {
|
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.
|
/// 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
|
// Wasmer 0.17.1 supports only one memory
|
||||||
const MEMORY_INDEX: u32 = 0;
|
const MEMORY_INDEX: u32 = 0;
|
||||||
|
|
||||||
let pages = self.wasmer_instance.context().memory(MEMORY_INDEX).size();
|
self.wasmer_instance.memory(MEMORY_INDEX).size()
|
||||||
pages.bytes().0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change the cloning Callable behaviour after changes of Wasmer API
|
// 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> {
|
) -> MResult<<WB as WasmBackend>::IO> {
|
||||||
use marine_it_interfaces::ITAstType;
|
use marine_it_interfaces::ITAstType;
|
||||||
//use wasmer_core::typed_func::DynamicFunc;
|
//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
|
// returns function that will be called from imports of Wasmer module
|
||||||
fn dyn_func_from_raw_import<'a, 'b, F, WB, I1, I2>(
|
fn dyn_func_from_raw_import<'a, 'b, F, WB, I1, I2>(
|
||||||
@ -320,7 +321,7 @@ impl<WB: WasmBackend> MModule<WB> {
|
|||||||
raw_import: F,
|
raw_import: F,
|
||||||
) -> <WB as WasmBackend>::DynamicFunc
|
) -> <WB as WasmBackend>::DynamicFunc
|
||||||
where
|
where
|
||||||
F: Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static,
|
F: Fn(&mut <WB as WasmBackend>::ExportContext, &[WValue]) -> Vec<WValue> + 'static,
|
||||||
WB: WasmBackend,
|
WB: WasmBackend,
|
||||||
I1: Iterator<Item = &'a IType>,
|
I1: Iterator<Item = &'a IType>,
|
||||||
I2: Iterator<Item = &'b IType>,
|
I2: Iterator<Item = &'b IType>,
|
||||||
@ -342,8 +343,9 @@ impl<WB: WasmBackend> MModule<WB> {
|
|||||||
interpreter: ITInterpreter<WB>,
|
interpreter: ITInterpreter<WB>,
|
||||||
import_namespace: String,
|
import_namespace: String,
|
||||||
import_name: String,
|
import_name: String,
|
||||||
) -> impl Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static {
|
) -> impl Fn(&mut <WB as WasmBackend>::ExportContext, &[WValue]) -> Vec<WValue> + 'static
|
||||||
move |_: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
|
{
|
||||||
|
move |_: &mut <WB as WasmBackend>::ExportContext, inputs: &[WValue]| -> Vec<WValue> {
|
||||||
use wasmer_it::interpreter::stack::Stackable;
|
use wasmer_it::interpreter::stack::Stackable;
|
||||||
|
|
||||||
use super::type_converters::wval_to_ival;
|
use super::type_converters::wval_to_ival;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user