mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
simplify fce_wit_interfaces
This commit is contained in:
parent
6a7dbb47c8
commit
59f9b7555f
61
crates/fce_wit_interfaces/src/interfaces/errors.rs
Normal file
61
crates/fce_wit_interfaces/src/interfaces/errors.rs
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FCEWITInterfacesError {
|
||||
/// WIT doesn't contain such type.
|
||||
NoSuchType(u32),
|
||||
|
||||
/// WIT doesn't contain such export.
|
||||
NoSuchExport(u32),
|
||||
|
||||
/// WIT doesn't contain such import.
|
||||
NoSuchImport(u32),
|
||||
|
||||
/// WIT doesn't contain such import.
|
||||
NoSuchAdapter(u32),
|
||||
}
|
||||
|
||||
impl Error for FCEWITInterfacesError {}
|
||||
|
||||
impl std::fmt::Display for FCEWITInterfacesError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
FCEWITInterfacesError::NoSuchType(type_id) => write!(
|
||||
f,
|
||||
"Loaded module doesn't contain type with idx = {}",
|
||||
type_id
|
||||
),
|
||||
FCEWITInterfacesError::NoSuchExport(export_type_id) => write!(
|
||||
f,
|
||||
"Loaded module doesn't contain export with type idx = {}",
|
||||
export_type_id
|
||||
),
|
||||
FCEWITInterfacesError::NoSuchImport(import_type_id) => write!(
|
||||
f,
|
||||
"Loaded module doesn't contain import with type idx = {}",
|
||||
import_type_id
|
||||
),
|
||||
FCEWITInterfacesError::NoSuchAdapter(adapter_type_id) => write!(
|
||||
f,
|
||||
"Loaded module doesn't contain adapter with type idx = {}",
|
||||
adapter_type_id
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::errors::FCEWITInterfacesError;
|
||||
|
||||
use wasmer_wit::interpreter::Instruction;
|
||||
use wasmer_wit::ast::*;
|
||||
use multimap::MultiMap;
|
||||
@ -98,12 +100,24 @@ impl<'a> FCEWITInterfaces<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn types(&self) -> impl Iterator<Item = &Type> {
|
||||
self.types.iter()
|
||||
}
|
||||
|
||||
pub fn type_by_idx(&self, idx: u32) -> Option<&Type> {
|
||||
self.types.get(idx as usize)
|
||||
}
|
||||
|
||||
pub fn types(&self) -> impl Iterator<Item = &Type> {
|
||||
self.types.iter()
|
||||
pub fn type_by_idx_r(&self, idx: u32) -> Result<&Type, FCEWITInterfacesError> {
|
||||
self.types
|
||||
.get(idx as usize)
|
||||
.ok_or_else(|| FCEWITInterfacesError::NoSuchType(idx))
|
||||
}
|
||||
|
||||
pub fn imports(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&CoreFunctionType, &(ImportName<'a>, ImportNamespace<'a>))> {
|
||||
self.imports.iter()
|
||||
}
|
||||
|
||||
pub fn import_by_type(
|
||||
@ -113,23 +127,37 @@ impl<'a> FCEWITInterfaces<'a> {
|
||||
self.imports.get(&import_type)
|
||||
}
|
||||
|
||||
pub fn imports(
|
||||
pub fn import_by_type_r(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&CoreFunctionType, &(ImportName<'a>, ImportNamespace<'a>))> {
|
||||
self.imports.iter()
|
||||
import_type: CoreFunctionType,
|
||||
) -> Result<&(ImportName<'a>, ImportNamespace<'a>), FCEWITInterfacesError> {
|
||||
self.imports
|
||||
.get(&import_type)
|
||||
.ok_or_else(|| FCEWITInterfacesError::NoSuchImport(import_type))
|
||||
}
|
||||
|
||||
pub fn adapters(&self) -> impl Iterator<Item = (&AdapterFunctionType, &Vec<Instruction>)> {
|
||||
self.adapters.iter()
|
||||
}
|
||||
|
||||
pub fn adapter_by_type(&self, adapter_type: AdapterFunctionType) -> Option<&Vec<Instruction>> {
|
||||
self.adapters.get(&adapter_type)
|
||||
}
|
||||
|
||||
pub fn adapter_by_type_r(
|
||||
&self,
|
||||
adapter_type: AdapterFunctionType,
|
||||
) -> Result<&Vec<Instruction>, FCEWITInterfacesError> {
|
||||
self.adapters
|
||||
.get(&adapter_type)
|
||||
.ok_or_else(|| FCEWITInterfacesError::NoSuchAdapter(adapter_type))
|
||||
}
|
||||
|
||||
pub fn export_by_type(&self, export_type: u32) -> Option<&ExportName<'a>> {
|
||||
self.exports.get(&export_type)
|
||||
}
|
||||
|
||||
pub fn exports(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (&CoreFunctionType, &ExportName<'a>)> {
|
||||
pub fn exports(&self) -> impl Iterator<Item = (&CoreFunctionType, &ExportName<'a>)> {
|
||||
self.exports.iter()
|
||||
}
|
||||
|
21
crates/fce_wit_interfaces/src/interfaces/mod.rs
Normal file
21
crates/fce_wit_interfaces/src/interfaces/mod.rs
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod errors;
|
||||
mod fce_wit_interfaces;
|
||||
|
||||
pub use fce_wit_interfaces::*;
|
||||
pub use errors::*;
|
@ -24,8 +24,8 @@
|
||||
unreachable_patterns
|
||||
)]
|
||||
|
||||
mod fce_wit_interfaces;
|
||||
mod interfaces;
|
||||
mod wit_parser;
|
||||
|
||||
pub use crate::wit_parser::*;
|
||||
pub use crate::fce_wit_interfaces::*;
|
||||
pub use crate::interfaces::*;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use super::custom::WIT_SECTION_NAME;
|
||||
use super::errors::WITParserError;
|
||||
use crate::fce_wit_interfaces::FCEWITInterfaces;
|
||||
use crate::interfaces::FCEWITInterfaces;
|
||||
|
||||
use walrus::{IdsToIndices, ModuleConfig};
|
||||
use wasmer_wit::ast::Interfaces;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod custom;
|
||||
mod errors;
|
||||
mod extractor;
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
|
||||
use fce_wit_interfaces::WITParserError;
|
||||
use fce_wit_interfaces::FCEWITInterfacesError;
|
||||
|
||||
use wasmer_wit::errors::InstructionError;
|
||||
use wasmer_runtime::error::{
|
||||
CallError, CompileError, CreationError, Error as WasmerError, ResolveError, RuntimeError,
|
||||
@ -134,3 +136,15 @@ impl From<WITParserError> for FCEError {
|
||||
FCEError::WITParseError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FCEWITInterfacesError> for FCEError {
|
||||
fn from(err: FCEWITInterfacesError) -> Self {
|
||||
FCEError::IncorrectWIT(format!("{}", err))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<()> for FCEError {
|
||||
fn from(_err: ()) -> Self {
|
||||
FCEError::IncorrectWIT(format!("failed to parse instructions for adapter type"))
|
||||
}
|
||||
}
|
||||
|
@ -115,33 +115,25 @@ impl FCEModule {
|
||||
) -> Result<HashMap<String, WITModuleFunc>, FCEError> {
|
||||
use fce_wit_interfaces::WITAstType;
|
||||
|
||||
wit
|
||||
.implementations()
|
||||
.filter_map(|(adapter_function_type, core_function_type)|
|
||||
wit.implementations()
|
||||
.filter_map(|(adapter_function_type, core_function_type)| {
|
||||
match wit.export_by_type(*core_function_type) {
|
||||
Some(export_function_name) => Some((adapter_function_type, *export_function_name)),
|
||||
Some(export_function_name) => {
|
||||
Some((adapter_function_type, *export_function_name))
|
||||
}
|
||||
// pass functions that aren't export
|
||||
None => None
|
||||
None => None,
|
||||
}
|
||||
)
|
||||
})
|
||||
.map(|(adapter_function_type, export_function_name)| {
|
||||
let adapter_instructions = wit.adapter_by_type(*adapter_function_type)
|
||||
.ok_or_else(|| FCEError::IncorrectWIT(
|
||||
format!("adapter function with idx = {} hasn't been found during extracting exports by implementations", adapter_function_type)
|
||||
))?;
|
||||
|
||||
let wit_type = wit.type_by_idx(*adapter_function_type).ok_or_else(
|
||||
// TODO: change error type
|
||||
|| FCEError::IncorrectWIT(format!(
|
||||
"{} function id is bigger than WIT interface types count",
|
||||
adapter_function_type
|
||||
)))?;
|
||||
let adapter_instructions = wit.adapter_by_type_r(*adapter_function_type)?;
|
||||
let wit_type = wit.type_by_idx_r(*adapter_function_type)?;
|
||||
|
||||
match wit_type {
|
||||
WITAstType::Function { inputs, outputs, .. } => {
|
||||
let interpreter: WITInterpreter = adapter_instructions.try_into().map_err(|_| FCEError::IncorrectWIT(
|
||||
format!("failed to parse instructions for adapter type {}", adapter_function_type)
|
||||
))?;
|
||||
WITAstType::Function {
|
||||
inputs, outputs, ..
|
||||
} => {
|
||||
let interpreter: WITInterpreter = adapter_instructions.try_into()?;
|
||||
|
||||
Ok((
|
||||
export_function_name.to_string(),
|
||||
@ -149,13 +141,13 @@ impl FCEModule {
|
||||
interpreter,
|
||||
inputs: inputs.clone(),
|
||||
outputs: outputs.clone(),
|
||||
}
|
||||
},
|
||||
))
|
||||
},
|
||||
}
|
||||
_ => Err(FCEError::IncorrectWIT(format!(
|
||||
"type with idx = {} isn't a function type",
|
||||
adapter_function_type
|
||||
)))
|
||||
))),
|
||||
}
|
||||
})
|
||||
.collect::<Result<HashMap<String, WITModuleFunc>, FCEError>>()
|
||||
@ -167,25 +159,29 @@ impl FCEModule {
|
||||
wit_instance: Arc<MaybeUninit<WITInstance>>,
|
||||
) -> Result<ImportObject, FCEError> {
|
||||
use fce_wit_interfaces::WITAstType;
|
||||
use super::type_converters::{itype_to_wtype, wval_to_ival};
|
||||
use wasmer_core::typed_func::DynamicFunc;
|
||||
use wasmer_core::types::FuncSig;
|
||||
use wasmer_core::vm::Ctx;
|
||||
|
||||
// returns function that will be called from imports of Wasmer module
|
||||
fn dyn_func_from_imports(
|
||||
fn dyn_func_from_raw_import(
|
||||
inputs: Vec<IType>,
|
||||
func: Box<dyn Fn(&mut Ctx, &[WValue]) -> Vec<WValue> + 'static>,
|
||||
) -> DynamicFunc<'static> {
|
||||
use wasmer_core::types::FuncSig;
|
||||
use super::type_converters::itype_to_wtype;
|
||||
|
||||
let signature = inputs.iter().map(itype_to_wtype).collect::<Vec<_>>();
|
||||
DynamicFunc::new(Arc::new(FuncSig::new(signature, vec![])), func)
|
||||
}
|
||||
|
||||
// creates a closure that is represent a WIT module import
|
||||
fn create_raw_import(
|
||||
wit_instance: Arc<MaybeUninit<WITInstance>>,
|
||||
interpreter: WITInterpreter,
|
||||
) -> Box<dyn for<'a, 'b> Fn(&'a mut Ctx, &'b [WValue]) -> Vec<WValue> + 'static> {
|
||||
Box::new(move |_: &mut Ctx, inputs: &[WValue]| -> Vec<WValue> {
|
||||
use super::type_converters::wval_to_ival;
|
||||
|
||||
// copy here because otherwise wit_instance will be consumed by the closure
|
||||
let wit_instance_callable = wit_instance.clone();
|
||||
let converted_inputs = inputs.iter().map(wval_to_ival).collect::<Vec<_>>();
|
||||
@ -205,47 +201,35 @@ impl FCEModule {
|
||||
|
||||
let namespaces = wit
|
||||
.implementations()
|
||||
.filter_map(|(adapter_function_type, core_function_type)|
|
||||
.filter_map(|(adapter_function_type, core_function_type)| {
|
||||
match wit.import_by_type(*core_function_type) {
|
||||
Some(import) => Some((adapter_function_type, *import)),
|
||||
// pass functions that aren't export
|
||||
None => None
|
||||
// skip functions that aren't export
|
||||
None => None,
|
||||
}
|
||||
)
|
||||
})
|
||||
.map(|(adapter_function_type, (import_namespace, import_name))| {
|
||||
let adapter_instructions = wit.adapter_by_type(*adapter_function_type)
|
||||
.ok_or_else(|| FCEError::IncorrectWIT(
|
||||
format!("adapter function with idx = {} hasn't been found during extracting adjusting wit imports", adapter_function_type)
|
||||
))?;
|
||||
|
||||
let wit_type = wit.type_by_idx(*adapter_function_type).ok_or_else(
|
||||
|| FCEError::IncorrectWIT(format!(
|
||||
"{} function id is bigger than WIT interface types count",
|
||||
adapter_function_type
|
||||
)))?;
|
||||
let adapter_instructions = wit.adapter_by_type_r(*adapter_function_type)?;
|
||||
let wit_type = wit.type_by_idx_r(*adapter_function_type)?;
|
||||
|
||||
match wit_type {
|
||||
WITAstType::Function { inputs, .. } => {
|
||||
let interpreter: WITInterpreter = adapter_instructions.try_into().map_err(|_| FCEError::IncorrectWIT(
|
||||
format!("failed to parse instructions for adapter type {}", adapter_function_type)
|
||||
))?;
|
||||
|
||||
let interpreter: WITInterpreter = adapter_instructions.try_into()?;
|
||||
let inner_import = create_raw_import(wit_instance.clone(), interpreter);
|
||||
let wit_import = dyn_func_from_imports(inputs.clone(), inner_import);
|
||||
let wit_import = dyn_func_from_raw_import(inputs.clone(), inner_import);
|
||||
|
||||
let mut namespace = Namespace::new();
|
||||
namespace.insert(import_name, wit_import);
|
||||
|
||||
Ok((
|
||||
import_namespace.to_string(),
|
||||
namespace
|
||||
))
|
||||
},
|
||||
Ok((import_namespace.to_string(), namespace))
|
||||
}
|
||||
_ => Err(FCEError::IncorrectWIT(format!(
|
||||
"type with idx = {} isn't a function type",
|
||||
adapter_function_type
|
||||
)))
|
||||
))),
|
||||
}
|
||||
}).collect::<Result<HashMap<String, Namespace>, FCEError>>()?;
|
||||
})
|
||||
.collect::<Result<HashMap<String, Namespace>, FCEError>>()?;
|
||||
|
||||
let mut import_object = ImportObject::new();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user