mirror of
https://github.com/fluencelabs/marine.git
synced 2025-03-14 21:40:49 +00:00
start moving marine-runtime to generic wasm backend
This commit is contained in:
parent
614a4cb078
commit
5e7dae9dcd
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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)?;
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
|
14
crates/wasm-backend-traits/Cargo.toml
Normal file
14
crates/wasm-backend-traits/Cargo.toml
Normal 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"] }
|
35
crates/wasm-backend-traits/src/lib.rs
Normal file
35
crates/wasm-backend-traits/src/lib.rs
Normal 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;
|
||||
}
|
13
crates/wasmer-backend/Cargo.toml
Normal file
13
crates/wasmer-backend/Cargo.toml
Normal 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" }
|
75
crates/wasmer-backend/src/lib.rs
Normal file
75
crates/wasmer-backend/src/lib.rs
Normal 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()
|
||||
}
|
||||
}*/
|
@ -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"}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user