start moving marine-runtime to generic wasm backend

This commit is contained in:
Valery Antopol 2022-02-25 22:28:28 +03:00
parent 614a4cb078
commit 5e7dae9dcd
22 changed files with 281 additions and 80 deletions

24
Cargo.lock generated
View File

@ -1610,6 +1610,7 @@ dependencies = [
"itertools 0.10.3",
"marine-it-interfaces 0.5.0",
"marine-module-interface 0.2.0",
"marine-wasm-backend-traits",
"nom",
"semver 0.11.0",
"serde",
@ -1658,6 +1659,7 @@ dependencies = [
"anyhow",
"chrono",
"marine-rs-sdk-main",
"marine-wasm-backend-traits",
"semver 0.11.0",
"serde",
"thiserror",
@ -1799,6 +1801,8 @@ dependencies = [
"marine-module-info-parser 0.2.2",
"marine-module-interface 0.2.0",
"marine-utils 0.4.0",
"marine-wasm-backend-traits",
"marine-wasmer-backend",
"multimap",
"once_cell",
"parity-wasm 0.42.2",
@ -1875,6 +1879,26 @@ checksum = "8dc5838acba84ce4d802d672afd0814fae0ae7098021ae5b06d975e70d09f812"
name = "marine-utils"
version = "0.4.0"
[[package]]
name = "marine-wasm-backend-traits"
version = "0.1.0"
dependencies = [
"thiserror",
"wasmer-interface-types-fl 0.21.1",
"wasmer-runtime-core-fl",
"wasmer-runtime-fl",
]
[[package]]
name = "marine-wasmer-backend"
version = "0.1.0"
dependencies = [
"marine-wasm-backend-traits",
"wasmer-interface-types-fl 0.21.1",
"wasmer-runtime-core-fl",
"wasmer-runtime-fl",
]
[[package]]
name = "marine-web-runtime"
version = "0.1.0"

View File

@ -7,6 +7,8 @@ members = [
"crates/min-it-version",
"crates/module-info-parser",
"crates/module-interface",
"crates/wasm-backend-traits",
"crates/wasmer-backend",
"crates/utils",
"examples/call_parameters",
"examples/greeting",

View File

@ -13,6 +13,7 @@ path = "src/lib.rs"
[dependencies]
marine-it-interfaces = { path = "../it-interfaces", version = "0.5.0" }
marine-module-interface = { path = "../module-interface", version = "0.2.0" }
marine-wasm-backend-traits = { path = "../wasm-backend-traits", version = "0.1.0"}
anyhow = "1.0.31"
walrus = "0.18.0"

View File

@ -20,7 +20,8 @@ use crate::ParserResult;
use walrus::IdsToIndices;
use wasmer_it::ast::Interfaces;
use wasmer_core::Module as WasmerModule;
//use wasmer_core::Module as WasmerModule;
use marine_wasm_backend_traits::Module as ModuleTrait;
use std::borrow::Cow;
use std::path::Path;
@ -42,7 +43,7 @@ where
}
/// Extracts IT section of provided Wasm binary and converts it to a MITInterfaces.
pub fn extract_it_from_module(wasmer_module: &WasmerModule) -> ParserResult<Interfaces<'_>> {
pub fn extract_it_from_module<M: ModuleTrait>(wasmer_module: &M) -> ParserResult<Interfaces<'_>> {
let wit_sections = wasmer_module
.custom_sections(IT_SECTION_NAME)
.ok_or(ITParserError::NoITSection)?;

View File

@ -14,6 +14,7 @@ path = "src/lib.rs"
marine-rs-sdk-main = "0.6.13"
wasmer-core = { package = "wasmer-runtime-core-fl", version = "=0.17.1" }
marine-wasm-backend-traits = { path = "../wasm-backend-traits", version = "0.1.0"}
anyhow = "1.0.31"
chrono = "0.4.19"

View File

@ -20,7 +20,8 @@ use super::SDKVersionError;
use crate::extract_custom_sections_by_name;
use crate::try_as_one_section;
use wasmer_core::Module as WasmerModule;
//use wasmer_core::Module as WasmerModule;
use marine_wasm_backend_traits::Module as ModuleTrait;
use marine_rs_sdk_main::VERSION_SECTION_NAME;
use walrus::ModuleConfig;
use walrus::Module;
@ -56,8 +57,8 @@ pub fn extract_from_module(wasm_module: &Module) -> ModuleInfoResult<Option<semv
Ok(Some(version))
}
pub fn extract_from_wasmer_module(
wasmer_module: &WasmerModule,
pub fn extract_from_wasmer_module<M: ModuleTrait>(
wasmer_module: &M,
) -> ModuleInfoResult<Option<semver::Version>> {
let sections = wasmer_module.custom_sections(VERSION_SECTION_NAME);

View File

@ -0,0 +1,14 @@
[package]
name = "marine-wasm-backend-traits"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
thiserror = "1.0.24"
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.21.1" }
wasmer-runtime = { package = "wasmer-runtime-fl", version = "=0.17.1" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc
wasmer-core = { package = "wasmer-runtime-core-fl", version = "=0.17.1", features = ["dynamicfunc-fat-closures"] }

View File

@ -0,0 +1,35 @@
use thiserror::Error;
pub struct Value {}
#[derive(Debug, Error)]
pub enum WasmBackendError {
#[error("Some error")]
SomeError,
}
pub type WasmBackendResult<T> = Result<T, WasmBackendError>;
pub trait WasmBackend: Clone + 'static {
type M: Module;
fn compile(wasm: &[u8]) -> WasmBackendResult<Self::M>;
}
pub trait Module {
type I: Instance;
fn custom_sections(&self, key: &str) -> Option<&[Vec<u8>]>;
fn instantiate(&self, imports: &wasmer_runtime::ImportObject) -> WasmBackendResult<Self::I>;
}
pub trait Instance {
fn export_iter<'a>(&'a self) -> Box<dyn Iterator<Item = (String, wasmer_runtime::Export)> + 'a>;
fn exports(&self) -> &wasmer_core::instance::Exports;
fn import_object(&self) -> &wasmer_runtime::ImportObject;
// maybe hide them inside impl
fn context(&self) -> &wasmer_core::vm::Ctx;
fn context_mut(&mut self) -> &mut wasmer_core::vm::Ctx;
}

View File

@ -0,0 +1,13 @@
[package]
name = "marine-wasmer-backend"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
marine-wasm-backend-traits = {path = "../wasm-backend-traits", version = "0.1.0"}
wasmer-runtime = { package = "wasmer-runtime-fl", version = "=0.17.1" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc
wasmer-core = { package = "wasmer-runtime-core-fl", version = "=0.17.1", features = ["dynamicfunc-fat-closures"] }
wasmer-it = { package = "wasmer-interface-types-fl", version = "0.21.1" }

View File

@ -0,0 +1,75 @@
use marine_wasm_backend_traits::WasmBackend;
use marine_wasm_backend_traits::WasmBackendResult;
use marine_wasm_backend_traits::WasmBackendError;
use marine_wasm_backend_traits::Module;
use marine_wasm_backend_traits::Instance;
#[derive(Clone)]
pub struct WasmerBackend {}
impl WasmBackend for WasmerBackend {
type M = WasmerModule;
fn compile(wasm: &[u8]) -> WasmBackendResult<WasmerModule> {
wasmer_runtime::compile(wasm).map_err(|_| {
WasmBackendError::SomeError
}).map(|module| {
WasmerModule { module }
})
}
}
pub struct WasmerModule {
module: wasmer_core::Module,
}
impl Module for WasmerModule {
type I = WasmerInstance;
fn custom_sections(&self, name: &str) -> Option<&[Vec<u8>]> {
self.module.custom_sections(name)
}
fn instantiate(&self, imports: &wasmer_runtime::ImportObject) -> WasmBackendResult<Self::I> {
self.module
.instantiate(&imports)
.map_err(|_| {
WasmBackendError::SomeError
})
.map(|instance| {WasmerInstance{instance}})
}
}
pub struct WasmerInstance {
instance: wasmer_core::Instance,
}
impl Instance for WasmerInstance {
fn export_iter<'a>(&'a self) -> Box<dyn Iterator<Item = (String, wasmer_runtime::Export)> + 'a> {
let exports = self.instance.exports();
Box::new(exports)
}
fn exports(&self) -> &wasmer_core::instance::Exports {
&self.instance.exports
}
fn import_object(&self) -> &wasmer_runtime::ImportObject {
&self.instance.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()}
}
/*
pub struct WasmerExportIter {
export_iter: Box<dyn Iterator<Item = (String, wasmer_runtime::Export)> + 'a>
}
impl<'a> Iterator for WasmerExportIter<'a> {
type Item = (String, wasmer_runtime::Export);
fn next(&mut self) -> Option<Self::Item> {
self.export_iter.as_mut().next()
}
}*/

View File

@ -18,6 +18,7 @@ marine-it-generator = { path = "../crates/it-generator", version = "0.6.0" }
marine-module-interface = { path = "../crates/module-interface", version = "0.2.0" }
marine-utils = { path = "../crates/utils", version = "0.4.0" }
marine-min-it-version = { path = "../crates/min-it-version", version = "0.1.0"}
marine-wasm-backend-traits = { path = "../crates/wasm-backend-traits", version = "0.1.0"}
wasmer-runtime = { package = "wasmer-runtime-fl", version = "=0.17.1" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc
@ -47,3 +48,4 @@ reqwest = "0.10.4"
bytes = "0.5.4"
tokio = { version = "0.2.20", features = ["blocking", "macros"] }
once_cell = "1.4.0"
marine-wasmer-backend = { path = "../crates/wasmer-backend", version = "0.1.0"}

View File

@ -18,6 +18,8 @@ use super::*;
use crate::module::MModule;
use crate::module::MRecordTypes;
use marine_wasm_backend_traits::WasmBackend;
use serde::Serialize;
use std::collections::hash_map::Entry;
@ -32,12 +34,12 @@ pub struct MModuleInterface<'a> {
}
/// The base struct of Marine, the Fluence compute runtime.
pub struct Marine {
pub struct Marine<WB: WasmBackend> {
// set of modules registered inside Marine
modules: HashMap<String, MModule>,
modules: HashMap<String, MModule<WB>>,
}
impl Marine {
impl<WB: WasmBackend> Marine<WB> {
pub fn new() -> Self {
Self {
modules: HashMap::new(),
@ -149,7 +151,7 @@ impl Marine {
records.into()
}
fn get_module_interface(module: &MModule) -> MModuleInterface<'_> {
fn get_module_interface(module: &MModule<WB>) -> MModuleInterface<'_> {
let record_types = module.export_record_types();
let function_signatures = module.get_exports_signatures().collect::<Vec<_>>();
@ -161,7 +163,7 @@ impl Marine {
}
}
impl Default for Marine {
impl<WB: WasmBackend> Default for Marine<WB> {
fn default() -> Self {
Self::new()
}

View File

@ -20,7 +20,7 @@ use crate::misc::PrepareError;
use marine_it_interfaces::MITInterfacesError;
use marine_it_parser::ITParserError;
use marine_module_interface::it_interface::ITInterfaceError;
use marine_wasm_backend_traits::WasmBackendError;
use wasmer_runtime::error as wasmer_error;
use thiserror::Error as ThisError;
@ -101,6 +101,9 @@ pub enum MError {
/// Incorrect IT section.
#[error("{0}")]
IncorrectWIT(String),
#[error("WASM BACKEND ERROR: {0}")]
WasmBackendError(WasmBackendError)
}
impl From<MITInterfacesError> for MError {
@ -132,3 +135,9 @@ impl From<()> for MError {
MError::IncorrectWIT("failed to parse instructions for adapter type".to_string())
}
}
impl From<WasmBackendError> for MError {
fn from(err: WasmBackendError) -> Self {
MError::WasmBackendError(err)
}
}

View File

@ -21,11 +21,13 @@ use marine_module_info_parser::sdk_version;
use marine_min_it_version::min_sdk_version;
use marine_min_it_version::min_it_version;
use wasmer_core::Module;
use marine_wasm_backend_traits::Module;
pub(crate) fn check_sdk_version(
//use wasmer_core::Module;
pub(crate) fn check_sdk_version<M: Module>(
name: impl Into<String>,
wasmer_module: &Module,
wasmer_module: &M,
) -> PrepareResult<()> {
let module_version = sdk_version::extract_from_wasmer_module(wasmer_module)?;
let module_version = match module_version {

View File

@ -21,12 +21,16 @@ use super::{IType, IRecordType, IFunctionArg, IValue, WValue};
use crate::MResult;
use crate::MModuleConfig;
use marine_wasm_backend_traits::WasmBackend;
use marine_wasm_backend_traits::Module;
use marine_wasm_backend_traits::Instance;
use marine_it_interfaces::MITInterfaces;
use marine_it_parser::extract_it_from_module;
use marine_utils::SharedString;
use wasmer_core::Instance as WasmerInstance;
//use wasmer_core::Instance as WasmerInstance;
use wasmer_core::import::Namespace;
use wasmer_runtime::compile;
//use wasmer_runtime::compile;
use wasmer_runtime::ImportObject;
use wasmer_it::interpreter::Interpreter;
@ -36,23 +40,23 @@ use std::mem::MaybeUninit;
use std::sync::Arc;
use std::rc::Rc;
type ITInterpreter =
Interpreter<ITInstance, ITExport, WITFunction, WITMemory, WITMemoryView<'static>>;
type ITInterpreter<WB> =
Interpreter<ITInstance<WB>, ITExport, WITFunction<WB>, WITMemory, WITMemoryView<'static>>;
#[derive(Clone)]
pub(super) struct ITModuleFunc {
interpreter: Arc<ITInterpreter>,
pub(super) struct ITModuleFunc<WB: WasmBackend> {
interpreter: Arc<ITInterpreter<WB>>,
pub(super) arguments: Rc<Vec<IFunctionArg>>,
pub(super) output_types: Rc<Vec<IType>>,
}
#[derive(Clone)]
pub(super) struct Callable {
pub(super) it_instance: Arc<ITInstance>,
pub(super) it_module_func: ITModuleFunc,
pub(super) struct Callable<WB: WasmBackend> {
pub(super) it_instance: Arc<ITInstance<WB>>,
pub(super) it_module_func: ITModuleFunc<WB>,
}
impl Callable {
impl<WB: WasmBackend> Callable<WB> {
pub fn call(&mut self, args: &[IValue]) -> MResult<Vec<IValue>> {
use wasmer_it::interpreter::stack::Stackable;
@ -67,13 +71,13 @@ impl Callable {
}
}
type ExportFunctions = HashMap<SharedString, Rc<Callable>>;
type ExportFunctions<WB> = HashMap<SharedString, Rc<Callable<WB>>>;
pub(crate) struct MModule {
pub(crate) struct MModule<WB: WasmBackend> {
// wasmer_instance is needed because WITInstance contains dynamic functions
// that internally keep pointer to it.
#[allow(unused)]
wasmer_instance: Box<WasmerInstance>,
wasmer_instance: Box<<<WB as WasmBackend>::M as Module>::I>,
// import_object is needed because ImportObject::extend doesn't really deep copy
// imports, so we need to store imports of this module to prevent their removing.
@ -91,21 +95,21 @@ pub(crate) struct MModule {
host_closures_import_object: ImportObject,
// TODO: replace with dyn Trait
export_funcs: ExportFunctions,
export_funcs: ExportFunctions<WB>,
// TODO: save refs instead copying of a record types HashMap.
/// Record types used in exported functions as arguments or return values.
export_record_types: MRecordTypes,
}
impl MModule {
impl<WB: WasmBackend> MModule<WB> {
pub(crate) fn new(
name: &str,
wasm_bytes: &[u8],
config: MModuleConfig,
modules: &HashMap<String, MModule>,
modules: &HashMap<String, MModule<WB>>,
) -> MResult<Self> {
let wasmer_module = compile(wasm_bytes)?;
let wasmer_module = WB::compile(wasm_bytes)?;
crate::misc::check_sdk_version(name, &wasmer_module)?;
let it = extract_it_from_module(&wasmer_module)?;
@ -125,14 +129,14 @@ impl MModule {
// it and the environment is single-threaded
*Arc::get_mut_unchecked(&mut wit_instance) =
MaybeUninit::new(ITInstance::new(&wasmer_instance, name, &mit, modules)?);
std::mem::transmute::<_, Arc<ITInstance>>(wit_instance)
std::mem::transmute::<_, Arc<ITInstance<WB>>>(wit_instance)
};
let (export_funcs, export_record_types) = Self::instantiate_exports(&it_instance, &mit)?;
// call _start to populate the WASI state of the module
#[rustfmt::skip]
if let Ok(start_func) = wasmer_instance.exports.get::<wasmer_runtime::Func<'_, (), ()>>("_start") {
if let Ok(start_func) = wasmer_instance.exports().get::<wasmer_runtime::Func<'_, (), ()>>("_start") {
start_func.call()?;
}
@ -199,7 +203,7 @@ impl MModule {
&self,
module_name: &str,
function_name: &str,
) -> MResult<Rc<Callable>> {
) -> MResult<Rc<Callable<WB>>> {
match self.export_funcs.get(function_name) {
Some(func) => Ok(func.clone()),
None => Err(MError::NoSuchFunction(
@ -259,9 +263,9 @@ impl MModule {
}
fn instantiate_exports(
it_instance: &Arc<ITInstance>,
it_instance: &Arc<ITInstance<WB>>,
mit: &MITInterfaces<'_>,
) -> MResult<(ExportFunctions, MRecordTypes)> {
) -> MResult<(ExportFunctions<WB>, MRecordTypes)> {
let module_interface = marine_module_interface::it_interface::get_interface(mit)?;
let export_funcs = module_interface
@ -270,7 +274,7 @@ impl MModule {
.map(|sign| {
let adapter_instructions = mit.adapter_by_type_r(sign.adapter_function_type)?;
let interpreter: ITInterpreter = adapter_instructions.clone().try_into()?;
let interpreter: ITInterpreter<WB> = adapter_instructions.clone().try_into()?;
let it_module_func = ITModuleFunc {
interpreter: Arc::new(interpreter),
arguments: sign.arguments.clone(),
@ -285,7 +289,7 @@ impl MModule {
Ok((shared_string, callable))
})
.collect::<MResult<ExportFunctions>>()?;
.collect::<MResult<ExportFunctions<WB>>>()?;
Ok((export_funcs, module_interface.export_record_types))
}
@ -293,7 +297,7 @@ impl MModule {
// this function deals only with import functions that have an adaptor implementation
fn adjust_wit_imports(
wit: &MITInterfaces<'_>,
wit_instance: Arc<MaybeUninit<ITInstance>>,
wit_instance: Arc<MaybeUninit<ITInstance<WB>>>,
) -> MResult<ImportObject> {
use marine_it_interfaces::ITAstType;
use wasmer_core::typed_func::DynamicFunc;
@ -317,9 +321,9 @@ impl MModule {
}
// creates a closure that is represent a IT module import
fn create_raw_import(
wit_instance: Arc<MaybeUninit<ITInstance>>,
interpreter: ITInterpreter,
fn create_raw_import<WB: WasmBackend + 'static>(
wit_instance: Arc<MaybeUninit<ITInstance<WB>>>,
interpreter: ITInterpreter<WB>,
import_namespace: String,
import_name: String,
) -> impl Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static {
@ -383,7 +387,7 @@ impl MModule {
arguments,
output_types,
} => {
let interpreter: ITInterpreter = adapter_instructions.clone().try_into()?;
let interpreter: ITInterpreter<WB> = adapter_instructions.clone().try_into()?;
let raw_import = create_raw_import(
wit_instance.clone(),

View File

@ -19,6 +19,8 @@ use super::{IType, IFunctionArg, IValue, WValue};
use super::marine_module::Callable;
use crate::MResult;
use marine_wasm_backend_traits::WasmBackend;
use wasmer_it::interpreter::wasm;
use wasmer_core::instance::DynFunc;
@ -26,26 +28,26 @@ use wasmer_core::instance::DynFunc;
use std::rc::Rc;
#[derive(Clone)]
enum WITFunctionInner {
enum WITFunctionInner<WB: WasmBackend> {
Export {
func: Rc<DynFunc<'static>>,
},
Import {
// TODO: use dyn Callable here
callable: Rc<Callable>,
callable: Rc<Callable<WB>>,
},
}
/// Represents all import and export functions that could be called from IT context by call-core.
#[derive(Clone)]
pub(super) struct WITFunction {
pub(super) struct WITFunction<WB: WasmBackend> {
name: String,
arguments: Rc<Vec<IFunctionArg>>,
outputs: Rc<Vec<IType>>,
inner: WITFunctionInner,
inner: WITFunctionInner<WB>,
}
impl WITFunction {
impl<WB: WasmBackend> WITFunction<WB> {
/// Creates functions from a "usual" (not IT) module export.
pub(super) fn from_export(dyn_func: DynFunc<'static>, name: String) -> MResult<Self> {
use super::type_converters::wtype_to_itype;
@ -83,7 +85,7 @@ impl WITFunction {
/// Creates function from a module import.
pub(super) fn from_import(
wit_module: &MModule,
wit_module: &MModule<WB>,
module_name: &str,
function_name: &str,
arguments: Rc<Vec<IFunctionArg>>,
@ -104,7 +106,7 @@ impl WITFunction {
}
}
impl wasm::structures::LocalImport for WITFunction {
impl<WB: WasmBackend> wasm::structures::LocalImport for WITFunction<WB> {
fn name(&self) -> &str {
self.name.as_str()
}

View File

@ -19,11 +19,16 @@ use super::marine_module::MModule;
use super::IRecordType;
use crate::MResult;
use marine_wasm_backend_traits::WasmBackend;
use marine_wasm_backend_traits::Module;
use marine_wasm_backend_traits::Instance;
use marine_it_interfaces::MITInterfaces;
use marine_it_interfaces::ITAstType;
use wasmer_it::interpreter::wasm;
use wasmer_it::interpreter::wasm::structures::{LocalImportIndex, Memory, TypedIndex};
use wasmer_core::Instance as WasmerInstance;
//use wasmer_core::Instance as WasmerInstance;
use std::collections::HashMap;
use std::rc::Rc;
@ -32,9 +37,9 @@ pub type MRecordTypes = HashMap<u64, Rc<IRecordType>>;
/// Contains all import and export functions that could be called from IT context by call-core.
#[derive(Clone)]
pub(super) struct ITInstance {
pub(super) struct ITInstance<WB: WasmBackend> {
/// IT functions indexed by id.
funcs: HashMap<usize, WITFunction>,
funcs: HashMap<usize, WITFunction<WB>>,
/// IT memories.
memories: Vec<WITMemory>,
@ -43,12 +48,12 @@ pub(super) struct ITInstance {
record_types_by_id: MRecordTypes,
}
impl ITInstance {
impl<WB: WasmBackend> ITInstance<WB> {
pub(super) fn new(
wasmer_instance: &WasmerInstance,
wasmer_instance: &<<WB as WasmBackend>::M as Module>::I,
module_name: &str,
wit: &MITInterfaces<'_>,
modules: &HashMap<String, MModule>,
modules: &HashMap<String, MModule<WB>>,
) -> MResult<Self> {
let mut exports = Self::extract_raw_exports(wasmer_instance, wit)?;
let imports = Self::extract_imports(module_name, modules, wit, exports.len())?;
@ -66,13 +71,13 @@ impl ITInstance {
})
}
fn extract_raw_exports(
wasmer_instance: &WasmerInstance,
fn extract_raw_exports<I: Instance>(
wasmer_instance: &I,
it: &MITInterfaces<'_>,
) -> MResult<HashMap<usize, WITFunction>> {
) -> MResult<HashMap<usize, WITFunction<WB>>> {
use wasmer_core::DynFunc;
let module_exports = &wasmer_instance.exports;
let module_exports = &wasmer_instance.exports();
it.exports()
.enumerate()
@ -95,10 +100,10 @@ impl ITInstance {
/// Extracts only those imports that don't have implementations.
fn extract_imports(
module_name: &str,
modules: &HashMap<String, MModule>,
modules: &HashMap<String, MModule<WB>>,
wit: &MITInterfaces<'_>,
start_index: usize,
) -> MResult<HashMap<usize, WITFunction>> {
) -> MResult<HashMap<usize, WITFunction<WB>>> {
wit.imports()
.filter(|import|
// filter out imports that have implementations
@ -136,11 +141,11 @@ impl ITInstance {
.collect::<MResult<HashMap<_, _>>>()
}
fn extract_memories(wasmer_instance: &WasmerInstance) -> Vec<WITMemory> {
fn extract_memories<I: Instance>(wasmer_instance: &I) -> Vec<WITMemory> {
use wasmer_core::export::Export::Memory;
let mut memories = wasmer_instance
.exports()
.export_iter()
.filter_map(|(_, export)| match export {
Memory(memory) => Some(WITMemory(memory)),
_ => None,
@ -148,7 +153,7 @@ impl ITInstance {
.collect::<Vec<_>>();
if let Some(Memory(memory)) = wasmer_instance
.import_object
.import_object()
.maybe_with_namespace("env", |env| env.get_export("memory"))
{
memories.push(WITMemory(memory));
@ -175,15 +180,15 @@ impl ITInstance {
}
}
impl<'v> wasm::structures::Instance<ITExport, WITFunction, WITMemory, WITMemoryView<'v>>
for ITInstance
impl<'v, WB: WasmBackend> wasm::structures::Instance<ITExport, WITFunction<WB>, WITMemory, WITMemoryView<'v>>
for ITInstance<WB>
{
fn export(&self, _export_name: &str) -> Option<&ITExport> {
// exports aren't used in this version of IT
None
}
fn local_or_import<I: TypedIndex + LocalImportIndex>(&self, index: I) -> Option<&WITFunction> {
fn local_or_import<I: TypedIndex + LocalImportIndex>(&self, index: I) -> Option<&WITFunction<WB>> {
self.funcs.get(&index.index())
}

View File

@ -24,9 +24,11 @@ static GREETING_WASM_BYTES: Lazy<Vec<u8>> = Lazy::new(|| {
.expect("../examples/greeting/artifacts/greeting.wasm should presence")
});
use marine_wasmer_backend::WasmerBackend;
#[test]
pub fn greeting_basic() {
let mut marine = Marine::new();
let mut marine = Marine::<WasmerBackend>::new();
marine
.load_module("greeting", &*GREETING_WASM_BYTES, <_>::default())
.unwrap_or_else(|e| panic!("can't load a module into Marine: {:?}", e));
@ -50,7 +52,7 @@ pub fn greeting_basic() {
#[test]
// test loading module with the same name twice
pub fn non_unique_module_name() {
let mut marine = Marine::new();
let mut marine = Marine::<WasmerBackend>::new();
let module_name = String::from("greeting");
marine
.load_module(&module_name, &*GREETING_WASM_BYTES, <_>::default())
@ -68,7 +70,7 @@ pub fn non_unique_module_name() {
#[allow(unused_variables)]
// test calling Marine with non-exist module and function names
pub fn non_exist_module_func() {
let mut marine = Marine::new();
let mut marine = Marine::<WasmerBackend>::new();
marine
.load_module("greeting", &*GREETING_WASM_BYTES, <_>::default())
.unwrap_or_else(|e| panic!("can't load a module into Marine: {:?}", e));

View File

@ -17,6 +17,8 @@
use marine::Marine;
use marine::IValue;
use marine_wasmer_backend::WasmerBackend;
#[test]
pub fn records() {
let effector_wasm_bytes = std::fs::read("../examples/records/artifacts/records_effector.wasm")
@ -25,7 +27,7 @@ pub fn records() {
let pure_wasm_bytes = std::fs::read("../examples/records/artifacts/records_pure.wasm")
.expect("../examples/records/artifacts/records_pure.wasm should presence");
let mut marine = Marine::new();
let mut marine = Marine::<WasmerBackend>::new();
let load_result = marine.load_module("pure", &pure_wasm_bytes, <_>::default());
assert!(load_result.is_err());

View File

@ -16,6 +16,7 @@
use marine::Marine;
use marine::IValue;
use marine_wasmer_backend::WasmerBackend;
const REDIS_DOWNLOAD_URL: &str =
"https://github.com/fluencelabs/redis/releases/download/v0.14.0_w/redis.wasm";
@ -35,7 +36,7 @@ pub async fn download(url: &str) -> bytes::Bytes {
async fn redis() {
let wasm_bytes = download(REDIS_DOWNLOAD_URL).await;
let mut marine = Marine::new();
let mut marine = Marine::<WasmerBackend>::new();
let module_name = "redis";
let config = <_>::default();
@ -95,7 +96,7 @@ async fn redis() {
async fn sqlite() {
let wasm_bytes = download(SQLITE_DOWNLOAD_URL).await;
let mut marine = Marine::new();
let mut marine = Marine::<WasmerBackend>::new();
let module_name = "sqlite";
let config = <_>::default();

View File

@ -68,13 +68,13 @@ impl Marine {
pub fn load_module<S: Into<String>>(
&mut self,
name: S,
wit_section_bytes: &[u8],
wasm_bytes: &[u8],
) -> MResult<()> {
self.load_module_(name.into(), wit_section_bytes)
self.load_module_(name.into(), wasm_bytes)
}
fn load_module_(&mut self, name: String, wit_section_bytes: &[u8]) -> MResult<()> {
let module = MModule::new(&name, wit_section_bytes)?;
fn load_module_(&mut self, name: String, wasm_bytes: &[u8]) -> MResult<()> {
let module = MModule::new(&name, wasm_bytes)?;
match self.modules.entry(name) {
Entry::Vacant(entry) => {

View File

@ -86,8 +86,11 @@ pub(crate) fn extract_it_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfac
#[allow(unused)]
impl MModule {
pub(crate) fn new(name: &str, wit_section_bytes: &[u8]) -> MResult<Self> {
let it = extract_it_from_bytes(wit_section_bytes)?;
pub(crate) fn new(name: &str, wasm_bytes: &[u8]) -> MResult<Self> {
// TODO: compile module
// TODO: extract it section
// TODO: extract sdk version
let it = extract_it_from_bytes(wasm_bytes)?;
crate::misc::check_it_version(name, &it.version)?;
let mit = MITInterfaces::new(it);