This commit is contained in:
vms 2020-11-07 23:16:03 +03:00
parent 2ef43ee778
commit ee93b8788b
17 changed files with 382 additions and 431 deletions

52
Cargo.lock generated
View File

@ -690,6 +690,7 @@ version = "0.1.10"
dependencies = [ dependencies = [
"fce-wit-parser", "fce-wit-parser",
"fluence-sdk-wit 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "fluence-sdk-wit 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools",
"once_cell", "once_cell",
"serde", "serde",
"serde_json", "serde_json",
@ -729,15 +730,6 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "fluence"
version = "0.2.8"
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
dependencies = [
"fluence-sdk-macro 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
"fluence-sdk-main 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
]
[[package]] [[package]]
name = "fluence" name = "fluence"
version = "0.2.8" version = "0.2.8"
@ -748,6 +740,15 @@ dependencies = [
"fluence-sdk-main 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "fluence-sdk-main 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "fluence"
version = "0.2.8"
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
dependencies = [
"fluence-sdk-macro 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
"fluence-sdk-main 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
]
[[package]] [[package]]
name = "fluence-app-service" name = "fluence-app-service"
version = "0.1.11" version = "0.1.11"
@ -786,14 +787,6 @@ dependencies = [
"wasmer-wasi-fl", "wasmer-wasi-fl",
] ]
[[package]]
name = "fluence-sdk-macro"
version = "0.2.8"
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
dependencies = [
"fluence-sdk-wit 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
]
[[package]] [[package]]
name = "fluence-sdk-macro" name = "fluence-sdk-macro"
version = "0.2.8" version = "0.2.8"
@ -804,13 +797,11 @@ dependencies = [
] ]
[[package]] [[package]]
name = "fluence-sdk-main" name = "fluence-sdk-macro"
version = "0.2.8" version = "0.2.8"
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30" source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
dependencies = [ dependencies = [
"fluence-sdk-macro 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)", "fluence-sdk-wit 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
"log",
"serde",
] ]
[[package]] [[package]]
@ -825,9 +816,20 @@ dependencies = [
] ]
[[package]] [[package]]
name = "fluence-sdk-wit" name = "fluence-sdk-main"
version = "0.2.8" version = "0.2.8"
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30" source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
dependencies = [
"fluence-sdk-macro 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
"log",
"serde",
]
[[package]]
name = "fluence-sdk-wit"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560baf91197ded38a99a5c94ff366a3dd971ebf33f5d987ecce31d3dedf86d17"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -840,8 +842,7 @@ dependencies = [
[[package]] [[package]]
name = "fluence-sdk-wit" name = "fluence-sdk-wit"
version = "0.2.8" version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
checksum = "560baf91197ded38a99a5c94ff366a3dd971ebf33f5d987ecce31d3dedf86d17"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2809,8 +2810,7 @@ dependencies = [
[[package]] [[package]]
name = "wasmer-interface-types-fl" name = "wasmer-interface-types-fl"
version = "0.17.15" version = "0.17.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/fluencelabs/interface-types?branch=impl_refactoring#4d1d48bbbf9fdd40677474e9ee8d123803534d60"
checksum = "88cf928132b7cc391adc52c47ae48aaebff01a85649b815b3e0142f8111c5529"
dependencies = [ dependencies = [
"log", "log",
"nom", "nom",

View File

@ -15,7 +15,8 @@ fce-wit-parser = { path = "../wit-parser", version = "0.1.9"}
fluence-sdk-wit = "0.2.8" fluence-sdk-wit = "0.2.8"
walrus = "0.17.0" walrus = "0.17.0"
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.17.15" } wasmer-wit = { package = "wasmer-interface-types-fl", git = "https://github.com/fluencelabs/interface-types", branch = "impl_refactoring" }
itertools = "0.9.0"
once_cell = "1.4.0" once_cell = "1.4.0"
serde = { version = "1.0.110", features = ["derive"] } serde = { version = "1.0.110", features = ["derive"] }
serde_json = "1.0.56" serde_json = "1.0.56"

View File

@ -14,12 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
use wasmer_wit::ast::Interfaces; use crate::IType;
use wasmer_wit::types::InterfaceType as IType; use crate::IFunctionArg;
use wasmer_wit::ast::FunctionArg as IFunctionArg;
use once_cell::sync::Lazy;
use std::rc::Rc; use once_cell::sync::Lazy;
pub(crate) struct ApiExportFuncDescriptor { pub(crate) struct ApiExportFuncDescriptor {
pub(crate) name: &'static str, pub(crate) name: &'static str,
@ -28,22 +26,6 @@ pub(crate) struct ApiExportFuncDescriptor {
pub(crate) output_types: Vec<IType>, pub(crate) output_types: Vec<IType>,
} }
impl ApiExportFuncDescriptor {
pub fn update_interfaces(&self, interfaces: &mut Interfaces<'_>) {
let func_type = wasmer_wit::ast::Type::Function {
arguments: Rc::new(self.arguments.clone()),
output_types: Rc::new(self.output_types.clone()),
};
interfaces.types.push(func_type);
let export = wasmer_wit::ast::Export {
name: self.name,
function_type: self.id,
};
interfaces.exports.push(export);
}
}
pub(crate) static ALLOCATE_FUNC: Lazy<ApiExportFuncDescriptor> = pub(crate) static ALLOCATE_FUNC: Lazy<ApiExportFuncDescriptor> =
Lazy::new(|| ApiExportFuncDescriptor { Lazy::new(|| ApiExportFuncDescriptor {
name: "allocate", name: "allocate",
@ -76,7 +58,7 @@ pub(crate) static GET_RESULT_SIZE_FUNC: Lazy<ApiExportFuncDescriptor> =
Lazy::new(|| ApiExportFuncDescriptor { Lazy::new(|| ApiExportFuncDescriptor {
name: "get_result_size", name: "get_result_size",
id: 2, id: 2,
arguments: vec![], arguments: Vec::<IFunctionArg>::new(),
output_types: vec![IType::I32], output_types: vec![IType::I32],
}); });
@ -84,7 +66,7 @@ pub(crate) static GET_RESULT_PTR_FUNC: Lazy<ApiExportFuncDescriptor> =
Lazy::new(|| ApiExportFuncDescriptor { Lazy::new(|| ApiExportFuncDescriptor {
name: "get_result_ptr", name: "get_result_ptr",
id: 3, id: 3,
arguments: vec![], arguments: Vec::<IFunctionArg>::new(),
output_types: vec![IType::I32], output_types: vec![IType::I32],
}); });

View File

@ -19,24 +19,25 @@ mod foreign_mod_instructions;
mod record_instructions; mod record_instructions;
mod utils; mod utils;
use crate::Result; pub(crate) use utils::add_function_type;
use wasmer_wit::types::InterfaceType as IType; use crate::*;
use wasmer_wit::ast::Interfaces; use crate::default_export_api_config::ApiExportFuncDescriptor;
use wasmer_wit::types::RecordType;
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap;
#[derive(PartialEq, Debug, Default)] #[derive(PartialEq, Debug, Default)]
pub(crate) struct WITResolver<'a> { pub(crate) struct WITResolver<'a> {
types: std::collections::HashMap<String, usize>, record_types: HashMap<String, usize>,
pub(crate) interfaces: Interfaces<'a>, unresolved_types_count: usize,
not_resolved_types_count: usize, function_types: HashMap<IFunctionType, u32>,
interfaces: Interfaces<'a>,
} }
impl<'a> WITResolver<'a> { impl<'a> WITResolver<'a> {
pub(crate) fn get_record_type_id(&self, record_name: &str) -> Result<usize> { pub(crate) fn get_record_type_id(&self, record_name: &str) -> Result<usize> {
match self.types.get(record_name) { match self.record_types.get(record_name) {
Some(type_index) => Ok(*type_index), Some(type_index) => Ok(*type_index),
None => Err(crate::errors::WITGeneratorError::CorruptedRecord(format!( None => Err(crate::errors::WITGeneratorError::CorruptedRecord(format!(
"Can't find record with name='{}', don't you forget to wrap it with #[fce]", "Can't find record with name='{}', don't you forget to wrap it with #[fce]",
@ -47,27 +48,22 @@ impl<'a> WITResolver<'a> {
// adds a stub for type with such a name if it wasn't found // adds a stub for type with such a name if it wasn't found
pub(crate) fn get_record_type_id_unchecked(&mut self, record_name: &str) -> usize { pub(crate) fn get_record_type_id_unchecked(&mut self, record_name: &str) -> usize {
use wasmer_wit::ast::Type; match self.record_types.get(record_name) {
match self.types.get(record_name) {
Some(type_index) => *type_index, Some(type_index) => *type_index,
None => { None => {
self.types self.record_types
.insert(record_name.to_string(), self.interfaces.types.len()); .insert(record_name.to_string(), self.interfaces.types.len());
self.interfaces self.interfaces
.types .types
.push(Type::Record(Rc::new(RecordType::default()))); .push(AstType::Record(Rc::new(IRecordType::default())));
self.not_resolved_types_count += 1; self.unresolved_types_count += 1;
self.interfaces.types.len() self.interfaces.types.len()
} }
} }
} }
pub(crate) fn get_record_type( pub(crate) fn get_record_type(&self, record_type_id: u64) -> Result<&IRecordType> {
&self,
record_type_id: u64,
) -> Result<&wasmer_wit::types::RecordType> {
if record_type_id >= self.interfaces.types.len() as u64 { if record_type_id >= self.interfaces.types.len() as u64 {
return Err(crate::errors::WITGeneratorError::CorruptedRecord(format!( return Err(crate::errors::WITGeneratorError::CorruptedRecord(format!(
"Can't find record with id {}, don't you forget to wrap it with #[fce]", "Can't find record with id {}, don't you forget to wrap it with #[fce]",
@ -76,35 +72,158 @@ impl<'a> WITResolver<'a> {
} }
match &self.interfaces.types[record_type_id as usize] { match &self.interfaces.types[record_type_id as usize] {
wasmer_wit::ast::Type::Function { .. } => { AstType::Function { .. } => {
panic!("internal error inside WITResolver: interfaces AST type should be record not record") panic!("internal error inside WITResolver: interfaces AST type should be record not record")
} }
wasmer_wit::ast::Type::Record(record_type) => Ok(record_type), AstType::Record(record_type) => Ok(record_type),
} }
} }
pub(crate) fn insert_record_type(&mut self, record: RecordType) { pub(crate) fn insert_record_type(&mut self, record: IRecordType) {
use wasmer_wit::ast::Type; match self.record_types.get(&record.name) {
match self.types.get(&record.name) {
Some(pos) => { Some(pos) => {
self.interfaces.types[*pos] = Type::Record(Rc::new(record)); self.interfaces.types[*pos] = AstType::Record(Rc::new(record));
self.not_resolved_types_count -= 1; self.unresolved_types_count -= 1;
} }
None => { None => {
self.types self.record_types
.insert(record.name.clone(), self.interfaces.types.len()); .insert(record.name.clone(), self.interfaces.types.len());
self.interfaces.types.push(Type::Record(Rc::new(record))); self.interfaces.types.push(AstType::Record(Rc::new(record)));
} }
} }
} }
pub(crate) fn unresolved_types_count(&self) -> usize { pub(crate) fn validate_records(&self) -> Result<()> {
self.not_resolved_types_count use crate::errors::WITGeneratorError::CorruptedRecord;
const TYPE_RESOLVE_RECURSION_LIMIT: u32 = 1024;
fn validate_record_type(
record_type: &IRecordType,
recursion_level: u32,
wit_resolver: &WITResolver<'_>,
) -> Result<()> {
if recursion_level >= TYPE_RESOLVE_RECURSION_LIMIT {
return Err(CorruptedRecord(String::from(
"too many inner structures level",
)));
}
for field in record_type.fields.iter() {
match &field.ty {
wasmer_wit::types::InterfaceType::Record(record_type_id) => {
let inner_record_type = wit_resolver.get_record_type(*record_type_id)?;
validate_record_type(
&inner_record_type,
recursion_level + 1,
wit_resolver,
)?;
}
_ => continue,
}
}
Ok(())
}
if self.unresolved_types_count != 0 {
return Err(CorruptedRecord(format!(
"{} types unresolved",
self.unresolved_types_count
)));
}
for ty in self.interfaces.types.iter() {
let record_type = match ty {
wasmer_wit::ast::Type::Record(ty) => ty,
_ => continue,
};
validate_record_type(record_type, 0, self)?;
}
Ok(())
}
pub(crate) fn insert_default_api(&mut self, function_descriptor: &ApiExportFuncDescriptor) {
let function_type = IFunctionType {
arguments: function_descriptor.arguments.clone(),
output_types: function_descriptor.output_types.clone(),
};
self.interfaces
.types
.push(AstType::Function(Rc::new(function_type)));
let export = AstExport {
name: function_descriptor.name,
function_type: function_descriptor.id,
};
self.interfaces.exports.push(export);
}
/// Insert a new function type if there is no one already,
/// return already inserted otherwise.
pub(crate) fn insert_function_type(&mut self, function_type: IFunctionType) -> u32 {
use std::collections::hash_map::Entry::*;
let next_id = (self.interfaces.types.len() + self.function_types.len()) as u32;
match self.function_types.entry(function_type) {
Occupied(entry) => *entry.get(),
Vacant(entry) => {
entry.insert(next_id);
next_id
}
}
}
/// Insert a new adapter, returns its id.
pub(crate) fn insert_adapter(&mut self, adapter: AstAdapter) -> u32 {
self.interfaces.adapters.push(adapter);
(self.interfaces.adapters.len() - 1) as u32
}
/// Insert a new implementation.
pub(crate) fn insert_implementation(&mut self, implementation: AstImplementation) -> u32 {
self.interfaces.implementations.push(implementation);
(self.interfaces.implementations.len() - 1) as u32
}
/// Insert a new export type and returns its id, that uniquely identifies its
/// and could be used in a call-core instruction.
pub(crate) fn insert_export_type(&mut self, export: AstExport<'a>) -> u32 {
let interfaces = &mut self.interfaces;
interfaces.exports.push(export);
(interfaces.exports.len() - 1) as u32
}
/// Insert a new import type and returns its id, that uniquely identifies its
/// and could be used in a call-core instruction.
pub(crate) fn insert_import_type(&mut self, import: AstImport<'a>) -> u32 {
let interfaces = &mut self.interfaces;
interfaces.imports.push(import);
(interfaces.imports.len() + interfaces.exports.len() - 1) as u32
}
/// Prepares types by insert collected function types and return resulted Interfaces.
pub(crate) fn finalize(mut self) -> Interfaces<'a> {
use itertools::Itertools;
let function_types: Vec<_> = self
.function_types
.into_iter()
.sorted_by(|(_, v1), (_, v2)| v1.cmp(&v2))
.map(|(function_type, _)| AstType::Function(Rc::new(function_type)))
.collect();
self.interfaces.types.extend(function_types);
self.interfaces
} }
} }
pub(crate) trait WITGenerator { pub(crate) trait WITGenerator {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()>; fn generate_wit<'ast_type, 'resolver>(&'ast_type self, wit_resolver: &'resolver mut WITResolver<'ast_type>) -> Result<()>;
} }

View File

@ -14,107 +14,82 @@
* limitations under the License. * limitations under the License.
*/ */
use super::add_function_type;
use super::WITGenerator; use super::WITGenerator;
use super::WITResolver; use super::WITResolver;
use super::utils::ptype_to_itype_checked; use super::utils::ptype_to_itype_checked;
use crate::default_export_api_config::*; use crate::default_export_api_config::*;
use crate::AstExport;
use crate::Result; use crate::Result;
use fluence_sdk_wit::AstFunctionItem; use fluence_sdk_wit::AstFunctionItem;
use fluence_sdk_wit::ParsedType; use fluence_sdk_wit::ParsedType;
use wasmer_wit::interpreter::Instruction; use wasmer_wit::interpreter::Instruction;
use wasmer_wit::ast::FunctionArg as IFunctionArg;
use std::rc::Rc;
impl WITGenerator for AstFunctionItem { impl WITGenerator for AstFunctionItem {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> { fn generate_wit<'ast_type, 'resolver>(&'ast_type self, wit_resolver: &'resolver mut WITResolver<'ast_type>) -> Result<()> {
use wasmer_wit::ast::Type; let arguments = &self.signature.arguments;
use wasmer_wit::ast::Adapter; let output_type = &self.signature.output_type;
let arguments = self let function_type_id = add_function_type(arguments, output_type, wit_resolver)?;
.signature let export_type = AstExport {
.arguments
.iter()
.map(|(arg_name, arg_type)| -> Result<IFunctionArg> {
Ok(IFunctionArg {
name: arg_name.clone(),
ty: ptype_to_itype_checked(arg_type, wit_resolver)?,
})
})
.collect::<Result<Vec<_>>>()?;
let arguments = Rc::new(arguments);
let output_types = match self.signature.output_type {
Some(ref output_type) => vec![ptype_to_itype_checked(output_type, wit_resolver)?],
None => vec![],
};
let output_types = Rc::new(output_types);
let interfaces = &mut wit_resolver.interfaces;
interfaces.types.push(Type::Function {
arguments: arguments.clone(),
output_types: output_types.clone(),
});
// TODO: replace with Wasm types
interfaces.types.push(Type::Function {
arguments,
output_types,
});
let adapter_idx = (interfaces.types.len() - 2) as u32;
let export_idx = (interfaces.types.len() - 1) as u32;
interfaces.exports.push(wasmer_wit::ast::Export {
name: &self.signature.name, name: &self.signature.name,
function_type: export_idx, function_type: function_type_id,
});
let mut instructions = self
.signature
.arguments
.iter()
.enumerate()
.try_fold::<_, _, Result<_>>(
Vec::new(),
|mut instructions, (arg_id, (_, input_type))| {
let mut new_instructions = input_type
.generate_instructions_for_input_type(arg_id as _, wit_resolver)?;
instructions.append(&mut new_instructions);
Ok(instructions)
},
)?;
let export_function_index = (wit_resolver.interfaces.exports.len() - 1) as u32;
instructions.push(Instruction::CallCore {
function_index: export_function_index,
});
instructions.extend(match &self.signature.output_type {
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
None => vec![],
});
let adapter = Adapter {
function_type: adapter_idx,
instructions,
}; };
let export_function_id = wit_resolver.insert_export_type(export_type);
wit_resolver.interfaces.adapters.push(adapter); let adapter_instructions = generate_export_adapter_instructions(
arguments,
output_type,
wit_resolver,
export_function_id,
)?;
let implementation = wasmer_wit::ast::Implementation { let adapter = crate::AstAdapter {
core_function_type: export_idx, function_type: function_type_id,
adapter_function_type: adapter_idx, instructions: adapter_instructions,
}; };
wit_resolver.interfaces.implementations.push(implementation); let adapter_id = wit_resolver.insert_adapter(adapter);
let implementation = crate::AstImplementation {
core_function_id: export_function_id,
adapter_function_id: adapter_id,
};
wit_resolver.insert_implementation(implementation);
Ok(()) Ok(())
} }
} }
fn generate_export_adapter_instructions(
arguments: &[(String, ParsedType)],
output_type: &Option<ParsedType>,
wit_resolver: &mut WITResolver<'_>,
export_function_id: u32,
) -> Result<Vec<Instruction>> {
let mut instructions = arguments.iter().enumerate().try_fold::<_, _, Result<_>>(
Vec::with_capacity(arguments.len()),
|mut instructions, (arg_id, (_, input_type))| {
let mut new_instructions =
input_type.generate_instructions_for_input_type(arg_id as _, wit_resolver)?;
instructions.append(&mut new_instructions);
Ok(instructions)
},
)?;
instructions.push(Instruction::CallCore {
function_index: export_function_id,
});
instructions.extend(match output_type {
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
None => vec![],
});
Ok(instructions)
}
/// Generate WIT instructions for a function. /// Generate WIT instructions for a function.
trait FnInstructionGenerator { trait FnInstructionGenerator {
fn generate_instructions_for_input_type<'a>( fn generate_instructions_for_input_type<'a>(

View File

@ -14,25 +14,22 @@
* limitations under the License. * limitations under the License.
*/ */
use super::add_function_type;
use super::WITGenerator; use super::WITGenerator;
use super::WITResolver; use super::WITResolver;
use super::utils::ptype_to_itype_checked; use super::utils::ptype_to_itype_checked;
use crate::*;
use crate::default_export_api_config::*; use crate::default_export_api_config::*;
use crate::Result;
use fluence_sdk_wit::AstExternModItem; use fluence_sdk_wit::AstExternModItem;
use fluence_sdk_wit::AstExternFnItem; use fluence_sdk_wit::AstExternFnItem;
use fluence_sdk_wit::ParsedType; use fluence_sdk_wit::ParsedType;
use wasmer_wit::ast::FunctionArg as IFunctionArg;
use wasmer_wit::interpreter::Instruction; use wasmer_wit::interpreter::Instruction;
use crate::instructions_generator::utils::wtype_to_itype;
use std::rc::Rc;
const HOST_NAMESPACE_NAME: &str = "host"; const HOST_NAMESPACE_NAME: &str = "host";
impl WITGenerator for AstExternModItem { impl WITGenerator for AstExternModItem {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> { fn generate_wit<'ast_type, 'resolver>(&'ast_type self, wit_resolver: &'resolver mut WITResolver<'ast_type>) -> Result<()> {
// host imports should be left as is // host imports should be left as is
if self.namespace == HOST_NAMESPACE_NAME { if self.namespace == HOST_NAMESPACE_NAME {
return Ok(()); return Ok(());
@ -51,86 +48,51 @@ fn generate_wit_for_import<'a>(
namespace: &'a str, namespace: &'a str,
wit_resolver: &mut WITResolver<'a>, wit_resolver: &mut WITResolver<'a>,
) -> Result<()> { ) -> Result<()> {
use wasmer_wit::ast::Type; let arguments = &import.signature.arguments;
use wasmer_wit::ast::Adapter; let output_type = &import.signature.output_type;
let arguments = import let function_type_id = add_function_type(arguments, output_type, wit_resolver)?;
.signature
.arguments
.iter()
.map(|(arg_name, arg_type)| -> Result<IFunctionArg> {
Ok(IFunctionArg {
name: arg_name.clone(),
ty: ptype_to_itype_checked(arg_type, wit_resolver)?,
})
})
.collect::<Result<Vec<_>>>()?;
let arguments = Rc::new(arguments);
let output_types = match import.signature.output_type {
Some(ref output_type) => vec![ptype_to_itype_checked(output_type, wit_resolver)?],
None => vec![],
};
let output_types = Rc::new(output_types);
let interfaces = &mut wit_resolver.interfaces;
interfaces.types.push(Type::Function {
arguments,
output_types,
});
let raw_inputs = import
.signature
.arguments
.iter()
.map(to_raw_input_types)
.flatten()
.collect::<Vec<_>>();
let raw_inputs = Rc::new(raw_inputs);
let raw_outputs = match import.signature.output_type {
Some(ref output_type) => to_raw_output_type(output_type)
.iter()
.map(wtype_to_itype)
.collect(),
None => vec![],
};
let raw_outputs = Rc::new(raw_outputs);
interfaces.types.push(Type::Function {
arguments: raw_inputs.clone(),
output_types: raw_outputs.clone(),
});
interfaces.types.push(Type::Function {
arguments: raw_inputs,
output_types: raw_outputs,
});
let adapter_idx = (interfaces.types.len() - 2) as u32;
let import_idx = (interfaces.types.len() - 3) as u32;
let raw_import_idx = (interfaces.types.len() - 1) as u32;
let link_name = match &import.link_name { let link_name = match &import.link_name {
Some(link_name) => link_name, Some(link_name) => link_name,
None => &import.signature.name, None => &import.signature.name,
}; };
let import_type = AstImport {
interfaces.imports.push(wasmer_wit::ast::Import {
namespace: &namespace,
name: link_name, name: link_name,
function_type: import_idx, namespace,
}); function_type: function_type_id,
};
let import_function_id = wit_resolver.insert_import_type(import_type);
interfaces.imports.push(wasmer_wit::ast::Import { let adapter_instructions = generate_import_adapter_instructions(
namespace: &namespace, arguments,
name: link_name, output_type,
function_type: raw_import_idx, wit_resolver,
}); import_function_id,
)?;
let mut instructions = import let adapter = crate::AstAdapter {
.signature function_type: function_type_id,
.arguments instructions: adapter_instructions,
};
let adapter_id = wit_resolver.insert_adapter(adapter);
let implementation = crate::AstImplementation {
core_function_id: import_function_id,
adapter_function_id: adapter_id,
};
wit_resolver.insert_implementation(implementation);
Ok(())
}
fn generate_import_adapter_instructions(
arguments: &[(String, ParsedType)],
output_type: &Option<ParsedType>,
wit_resolver: &mut WITResolver<'_>,
import_function_id: u32,
) -> Result<Vec<Instruction>> {
let mut instructions = arguments
.iter() .iter()
.try_fold::<_, _, Result<_>>( .try_fold::<_, _, Result<_>>(
(0, Vec::new()), (0, Vec::new()),
@ -144,32 +106,16 @@ fn generate_wit_for_import<'a>(
)? )?
.1; .1;
// TODO: refactor
let import_function_index = (wit_resolver.interfaces.exports.len()
+ wit_resolver.interfaces.imports.len() / 2
- 1) as u32;
instructions.push(Instruction::CallCore { instructions.push(Instruction::CallCore {
function_index: import_function_index, function_index: import_function_id,
}); });
instructions.extend(match &import.signature.output_type { instructions.extend(match output_type {
Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?, Some(output_type) => output_type.generate_instructions_for_output_type(wit_resolver)?,
None => vec![], None => vec![],
}); });
let adapter = Adapter { Ok(instructions)
function_type: adapter_idx,
instructions,
};
wit_resolver.interfaces.adapters.push(adapter);
let implementation = wasmer_wit::ast::Implementation {
core_function_type: raw_import_idx,
adapter_function_type: adapter_idx,
};
wit_resolver.interfaces.implementations.push(implementation);
Ok(())
} }
/// Generate WIT instructions for a foreign mod. /// Generate WIT instructions for a foreign mod.
@ -277,60 +223,3 @@ impl ForeignModInstructionGenerator for ParsedType {
Ok(instructions) Ok(instructions)
} }
} }
use fluence_sdk_wit::RustType;
use wasmer_wit::types::InterfaceType as IType;
pub fn to_raw_input_types(arg: &(String, ParsedType)) -> Vec<IFunctionArg> {
match arg.1 {
ParsedType::Boolean
| ParsedType::I8
| ParsedType::I16
| ParsedType::I32
| ParsedType::U8
| ParsedType::U16
| ParsedType::U32
| ParsedType::Record(_) => vec![IFunctionArg {
name: arg.0.clone(),
ty: IType::I32,
}],
ParsedType::I64 | ParsedType::U64 => vec![IFunctionArg {
name: arg.0.clone(),
ty: IType::I64,
}],
ParsedType::F32 => vec![IFunctionArg {
name: arg.0.clone(),
ty: IType::F32,
}],
ParsedType::F64 => vec![IFunctionArg {
name: arg.0.clone(),
ty: IType::F64,
}],
ParsedType::Utf8String | ParsedType::Vector(_) => vec![
IFunctionArg {
name: format!("{}_ptr", arg.0),
ty: IType::I32,
},
IFunctionArg {
name: format!("{}_ptr", arg.0),
ty: IType::I32,
},
],
}
}
pub fn to_raw_output_type(ty: &ParsedType) -> Vec<RustType> {
match ty {
ParsedType::Boolean
| ParsedType::I8
| ParsedType::I16
| ParsedType::I32
| ParsedType::U8
| ParsedType::U16
| ParsedType::U32 => vec![RustType::I32],
ParsedType::I64 | ParsedType::U64 => vec![RustType::I64],
ParsedType::F32 => vec![RustType::F32],
ParsedType::F64 => vec![RustType::F64],
ParsedType::Utf8String | ParsedType::Vector(_) | ParsedType::Record(_) => vec![],
}
}

View File

@ -25,13 +25,15 @@ use wasmer_wit::types::RecordType;
use wasmer_wit::vec1::Vec1; use wasmer_wit::vec1::Vec1;
impl WITGenerator for AstRecordItem { impl WITGenerator for AstRecordItem {
fn generate_wit<'a>(&'a self, wit_resolver: &mut WITResolver<'a>) -> Result<()> { fn generate_wit<'ast_type, 'resolver>(&'ast_type self, wit_resolver: &'resolver mut WITResolver<'ast_type>) -> Result<()> {
use super::utils::ptype_to_itype_unchecked;
let fields = self let fields = self
.fields .fields
.iter() .iter()
.map(|field| IRecordFieldType { .map(|field| IRecordFieldType {
name: field.name.clone().unwrap_or_default(), name: field.name.clone().unwrap_or_default(),
ty: super::utils::ptype_to_itype_unchecked(&field.ty, wit_resolver), ty: ptype_to_itype_unchecked(&field.ty, wit_resolver),
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View File

@ -14,12 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
use super::IType; use crate::IType;
use crate::IFunctionArg;
use crate::IFunctionType;
use crate::instructions_generator::WITResolver; use crate::instructions_generator::WITResolver;
use crate::Result; use crate::Result;
use fluence_sdk_wit::ParsedType; use fluence_sdk_wit::ParsedType;
use fluence_sdk_wit::RustType;
// return error if there is no record with such name // return error if there is no record with such name
pub(crate) fn ptype_to_itype_checked( pub(crate) fn ptype_to_itype_checked(
@ -78,17 +79,30 @@ pub(crate) fn ptype_to_itype_unchecked(
} }
} }
pub(crate) fn wtype_to_itype(pty: &RustType) -> IType { pub(crate) fn add_function_type(
match pty { arguments: &Vec<(String, ParsedType)>,
RustType::I8 => IType::S8, output_type: &Option<ParsedType>,
RustType::I16 => IType::S16, wit_resolver: &mut WITResolver<'_>,
RustType::I32 => IType::S32, ) -> Result<u32> {
RustType::I64 => IType::S64, let arguments = arguments
RustType::U8 => IType::U8, .iter()
RustType::U16 => IType::U16, .map(|(arg_name, arg_type)| -> Result<IFunctionArg> {
RustType::U32 => IType::U32, Ok(IFunctionArg {
RustType::U64 => IType::U64, name: arg_name.clone(),
RustType::F32 => IType::F32, ty: ptype_to_itype_checked(&arg_type, wit_resolver)?,
RustType::F64 => IType::F64, })
} })
.collect::<Result<Vec<_>>>()?;
let output_types = match output_type {
Some(output_type) => vec![ptype_to_itype_checked(output_type, wit_resolver)?],
None => vec![],
};
let function_type = IFunctionType {
arguments,
output_types,
};
Ok(wit_resolver.insert_function_type(function_type))
} }

View File

@ -20,9 +20,6 @@ use crate::instructions_generator::WITGenerator;
use crate::instructions_generator::WITResolver; use crate::instructions_generator::WITResolver;
use crate::Result; use crate::Result;
pub use fluence_sdk_wit::FCEAst;
use wasmer_wit::ast::Interfaces;
/// Parse generated by rust-sdk AST types, generate instructions and embed them to Wasm file. /// Parse generated by rust-sdk AST types, generate instructions and embed them to Wasm file.
pub fn embed_wit(path: std::path::PathBuf) -> Result<()> { pub fn embed_wit(path: std::path::PathBuf) -> Result<()> {
let wasm_module = walrus::ModuleConfig::new() let wasm_module = walrus::ModuleConfig::new()
@ -30,9 +27,12 @@ pub fn embed_wit(path: std::path::PathBuf) -> Result<()> {
.map_err(|e| WITGeneratorError::IOError(format!("{:?} can't be parsed: {:?}", path, e)))?; .map_err(|e| WITGeneratorError::IOError(format!("{:?} can't be parsed: {:?}", path, e)))?;
let module_ast = wasm_ast_extractor(&wasm_module)?; let module_ast = wasm_ast_extractor(&wasm_module)?;
let interfaces = generate_interfaces(&module_ast)?; let mut wit_resolver = WITResolver::default();
generate_interfaces(&module_ast, &mut wit_resolver)?;
let wasm_module = fce_wit_parser::delete_wit_section(wasm_module); let wasm_module = fce_wit_parser::delete_wit_section(wasm_module);
let interfaces = wit_resolver.finalize();
let mut wasm_module = fce_wit_parser::embed_wit(wasm_module, &interfaces); let mut wasm_module = fce_wit_parser::embed_wit(wasm_module, &interfaces);
wasm_module.emit_wasm_file(path).map_err(|e| { wasm_module.emit_wasm_file(path).map_err(|e| {
@ -55,13 +55,15 @@ fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<ModuleAST> {
let mut extern_mods: Vec<AstExternModItem> = Vec::new(); let mut extern_mods: Vec<AstExternModItem> = Vec::new();
// consider only sections name of that starts with GENERATED_SECTION_PREFIX // consider only sections name of that starts with GENERATED_SECTION_PREFIX
for custom_module in wasm_module.customs.iter().filter(|(_, section)| { let custom_sections = wasm_module.customs.iter().filter(|(_, section)| {
section section
.name() .name()
.starts_with(fluence_sdk_wit::GENERATED_SECTION_PREFIX) .starts_with(fluence_sdk_wit::GENERATED_SECTION_PREFIX)
}) { });
for custom_section in custom_sections {
let default_ids = walrus::IdsToIndices::default(); let default_ids = walrus::IdsToIndices::default();
let raw_data = custom_module.1.data(&default_ids); let raw_data = custom_section.1.data(&default_ids);
let decoded_json: FCEAst = serde_json::from_slice(&raw_data)?; let decoded_json: FCEAst = serde_json::from_slice(&raw_data)?;
match decoded_json { match decoded_json {
FCEAst::Record(record) => records.push(record), FCEAst::Record(record) => records.push(record),
@ -77,77 +79,33 @@ fn wasm_ast_extractor(wasm_module: &walrus::Module) -> Result<ModuleAST> {
}) })
} }
fn generate_interfaces(module_ast: &ModuleAST) -> Result<Interfaces<'_>> { fn generate_interfaces<'ast, 'wit_resolver>(
let mut wit_resolver = WITResolver::default(); module_ast: &'ast ModuleAST,
generate_default_export_api(&mut wit_resolver.interfaces); wit_resolver: &'wit_resolver mut WITResolver<'ast>,
) -> Result<()> {
generate_default_export_api(wit_resolver);
for record in &module_ast.records { for record in &module_ast.records {
record.generate_wit(&mut wit_resolver)?; record.generate_wit(wit_resolver)?;
} }
validate_records(&wit_resolver)?; wit_resolver.validate_records()?;
for function in &module_ast.functions { for function in &module_ast.functions {
function.generate_wit(&mut wit_resolver)?; function.generate_wit(wit_resolver)?;
} }
for extern_mod in &module_ast.extern_mods { for extern_mod in &module_ast.extern_mods {
extern_mod.generate_wit(&mut wit_resolver)?; extern_mod.generate_wit(wit_resolver)?;
}
Ok(wit_resolver.interfaces)
}
fn generate_default_export_api(interfaces: &mut Interfaces<'_>) {
// TODO: the order is matter
ALLOCATE_FUNC.update_interfaces(interfaces);
DEALLOCATE_FUNC.update_interfaces(interfaces);
GET_RESULT_SIZE_FUNC.update_interfaces(interfaces);
GET_RESULT_PTR_FUNC.update_interfaces(interfaces);
SET_RESULT_SIZE_FUNC.update_interfaces(interfaces);
SET_RESULT_PTR_FUNC.update_interfaces(interfaces);
}
fn validate_records(wit_resolver: &WITResolver<'_>) -> Result<()> {
const TYPE_RESOLVE_RECURSION_LIMIT: u32 = 1024;
fn validate_record_type(
record_type: &wasmer_wit::types::RecordType,
recursion_level: u32,
wit_resolver: &WITResolver<'_>,
) -> Result<()> {
if recursion_level >= TYPE_RESOLVE_RECURSION_LIMIT {
return Err(WITGeneratorError::CorruptedRecord(String::from(
"too many inner structures level",
)));
}
for field in record_type.fields.iter() {
match &field.ty {
wasmer_wit::types::InterfaceType::Record(record_type_id) => {
let inner_record_type = wit_resolver.get_record_type(*record_type_id)?;
validate_record_type(&inner_record_type, recursion_level + 1, wit_resolver)?;
}
_ => continue,
}
}
Ok(())
}
if wit_resolver.unresolved_types_count() != 0 {
return Err(WITGeneratorError::CorruptedRecord(format!(
"{} types unresolved",
wit_resolver.unresolved_types_count()
)));
}
for ty in wit_resolver.interfaces.types.iter() {
let record_type = match ty {
wasmer_wit::ast::Type::Record(ty) => ty,
_ => continue,
};
validate_record_type(record_type, 0, wit_resolver)?;
} }
Ok(()) Ok(())
} }
fn generate_default_export_api(wit_resolver: &mut WITResolver<'_>) {
// TODO: the order is matter
wit_resolver.insert_default_api(&ALLOCATE_FUNC);
wit_resolver.insert_default_api(&DEALLOCATE_FUNC);
wit_resolver.insert_default_api(&GET_RESULT_SIZE_FUNC);
wit_resolver.insert_default_api(&GET_RESULT_PTR_FUNC);
wit_resolver.insert_default_api(&SET_RESULT_SIZE_FUNC);
wit_resolver.insert_default_api(&SET_RESULT_PTR_FUNC);
}

View File

@ -34,3 +34,14 @@ pub use interface_generator::embed_wit;
pub use errors::WITGeneratorError; pub use errors::WITGeneratorError;
pub(crate) type Result<T> = std::result::Result<T, WITGeneratorError>; pub(crate) type Result<T> = std::result::Result<T, WITGeneratorError>;
pub(crate) use wasmer_wit::ast::Interfaces;
pub(crate) use wasmer_wit::ast::Adapter as AstAdapter;
pub(crate) use wasmer_wit::ast::Type as AstType;
pub(crate) use wasmer_wit::ast::Export as AstExport;
pub(crate) use wasmer_wit::ast::Import as AstImport;
pub(crate) use wasmer_wit::ast::Implementation as AstImplementation;
pub(crate) use wasmer_wit::types::InterfaceType as IType;
pub(crate) use wasmer_wit::types::RecordType as IRecordType;
pub(crate) use wasmer_wit::types::FunctionArg as IFunctionArg;
pub(crate) use wasmer_wit::types::FunctionType as IFunctionType;

View File

@ -11,5 +11,5 @@ name = "fce_wit_interfaces"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.17.15" } wasmer-wit = { package = "wasmer-interface-types-fl", git = "https://github.com/fluencelabs/interface-types", branch = "impl_refactoring" }
multimap = "0.8.1" multimap = "0.8.1"

View File

@ -77,8 +77,8 @@ impl<'a> FCEWITInterfaces<'a> {
.iter() .iter()
.map(|implementation| { .map(|implementation| {
( (
implementation.adapter_function_type, implementation.adapter_function_id,
implementation.core_function_type, implementation.core_function_id,
) )
}) })
.collect::<MultiMap<_, _>>(); .collect::<MultiMap<_, _>>();
@ -88,8 +88,8 @@ impl<'a> FCEWITInterfaces<'a> {
.iter() .iter()
.map(|implementation| { .map(|implementation| {
( (
implementation.core_function_type, implementation.core_function_id,
implementation.adapter_function_type, implementation.adapter_function_id,
) )
}) })
.collect::<MultiMap<_, _>>(); .collect::<MultiMap<_, _>>();
@ -189,15 +189,15 @@ impl<'a> FCEWITInterfaces<'a> {
pub fn adapter_types_by_core_type( pub fn adapter_types_by_core_type(
&self, &self,
core_function_type: CoreFunctionType, core_function_id: CoreFunctionType,
) -> Option<&Vec<AdapterFunctionType>> { ) -> Option<&Vec<AdapterFunctionType>> {
self.core_type_to_adapter.get_vec(&core_function_type) self.core_type_to_adapter.get_vec(&core_function_id)
} }
pub fn core_types_by_adapter_type( pub fn core_types_by_adapter_type(
&self, &self,
adapter_function_type: AdapterFunctionType, adapter_function_id: AdapterFunctionType,
) -> Option<&Vec<CoreFunctionType>> { ) -> Option<&Vec<CoreFunctionType>> {
self.adapter_type_to_core.get_vec(&adapter_function_type) self.adapter_type_to_core.get_vec(&adapter_function_id)
} }
} }

View File

@ -16,4 +16,4 @@ fce-wit-interfaces = { path = "../wit-interfaces", version = "0.1.7" }
anyhow = "1.0.31" anyhow = "1.0.31"
walrus = "0.17.0" walrus = "0.17.0"
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0"} wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0"}
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.17.15" } wasmer-wit = { package = "wasmer-interface-types-fl", git = "https://github.com/fluencelabs/interface-types", branch = "impl_refactoring" }

View File

@ -18,7 +18,7 @@ fce-utils = { path = "../crates/utils", version = "0.1.0" }
wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" } wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc # dynamicfunc-fat-closures allows using state inside DynamicFunc
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0", features = ["dynamicfunc-fat-closures"] } wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0", features = ["dynamicfunc-fat-closures"] }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.17.15" } wasmer-wit = { package = "wasmer-interface-types-fl", git = "https://github.com/fluencelabs/interface-types", branch = "impl_refactoring" }
wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.0" } wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.0" }
multimap = "0.8.1" multimap = "0.8.1"

View File

@ -249,24 +249,24 @@ impl FCEModule {
use fce_wit_interfaces::WITAstType; use fce_wit_interfaces::WITAstType;
wit.implementations() wit.implementations()
.filter_map(|(adapter_function_type, core_function_type)| { .filter_map(|(adapter_function_id, core_function_id)| {
match wit.exports_by_type(*core_function_type) { match wit.exports_by_type(*core_function_id) {
Some(export_function_name) => { Some(export_function_name) => {
Some((adapter_function_type, export_function_name)) Some((adapter_function_id, export_function_name))
} }
// pass functions that aren't export // pass functions that aren't export
None => None, None => None,
} }
}) })
.map(|(adapter_function_type, export_function_names)| { .map(|(adapter_function_id, export_function_names)| {
export_function_names export_function_names
.iter() .iter()
.map(move |export_function_name| (*adapter_function_type, export_function_name)) .map(move |export_function_name| (*adapter_function_id, export_function_name))
}) })
.flatten() .flatten()
.map(|(adapter_function_type, export_function_name)| { .map(|(adapter_function_id, export_function_name)| {
let adapter_instructions = wit.adapter_by_type_r(adapter_function_type)?; let adapter_instructions = wit.adapter_by_type_r(adapter_function_id)?;
let wit_type = wit.type_by_idx_r(adapter_function_type)?; let wit_type = wit.type_by_idx_r(adapter_function_id)?;
match wit_type { match wit_type {
WITAstType::Function { WITAstType::Function {
@ -291,7 +291,7 @@ impl FCEModule {
} }
_ => Err(FCEError::IncorrectWIT(format!( _ => Err(FCEError::IncorrectWIT(format!(
"type with idx = {} isn't a function type", "type with idx = {} isn't a function type",
adapter_function_type adapter_function_id
))), ))),
} }
}) })
@ -373,22 +373,22 @@ impl FCEModule {
let wit_import_funcs = wit let wit_import_funcs = wit
.implementations() .implementations()
.filter_map(|(adapter_function_type, core_function_type)| { .filter_map(|(adapter_function_id, core_function_id)| {
match wit.imports_by_type(*core_function_type) { match wit.imports_by_type(*core_function_id) {
Some(import) => Some((adapter_function_type, import)), Some(import) => Some((adapter_function_id, import)),
// skip functions that aren't import // skip functions that aren't import
None => None, None => None,
} }
}) })
.map(|(adapter_function_type, import_function_names)| { .map(|(adapter_function_id, import_function_names)| {
import_function_names import_function_names
.iter() .iter()
.map(move |import_function_name| (*adapter_function_type, import_function_name)) .map(move |import_function_name| (*adapter_function_id, import_function_name))
}) })
.flatten() .flatten()
.map(|(adapter_function_type, (import_namespace, import_name))| { .map(|(adapter_function_id, (import_namespace, import_name))| {
let adapter_instructions = wit.adapter_by_type_r(adapter_function_type)?; let adapter_instructions = wit.adapter_by_type_r(adapter_function_id)?;
let wit_type = wit.type_by_idx_r(adapter_function_type)?; let wit_type = wit.type_by_idx_r(adapter_function_id)?;
match wit_type { match wit_type {
WITAstType::Function { WITAstType::Function {
@ -415,7 +415,7 @@ impl FCEModule {
} }
_ => Err(FCEError::IncorrectWIT(format!( _ => Err(FCEError::IncorrectWIT(format!(
"type with idx = {} isn't a function type", "type with idx = {} isn't a function type",
adapter_function_type adapter_function_id
))), ))),
} }
}) })

View File

@ -79,7 +79,7 @@ impl WITInstance {
let export_func = module_exports.get(export.name)?; let export_func = module_exports.get(export.name)?;
unsafe { unsafe {
// TODO: refactor this with new Wasmer API when it is ready // TODO: refactor this with new Wasmer API when it is ready
// here it is safe because dyn func is never lives WITInstance // here it is safe because dyn func is never leaves WITInstance
let export_func = let export_func =
std::mem::transmute::<DynFunc<'_>, DynFunc<'static>>(export_func); std::mem::transmute::<DynFunc<'_>, DynFunc<'static>>(export_func);
Ok(( Ok((

View File

@ -15,7 +15,7 @@ wasmer-runtime = { package = "wasmer-runtime-fl", version = "0.17.0" }
# dynamicfunc-fat-closures allows using state inside DynamicFunc # dynamicfunc-fat-closures allows using state inside DynamicFunc
wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0", features = ["dynamicfunc-fat-closures"] } wasmer-core = { package = "wasmer-runtime-core-fl", version = "0.17.0", features = ["dynamicfunc-fat-closures"] }
wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.0" } wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.0" }
wasmer-wit = { package = "wasmer-interface-types-fl", version = "=0.17.15" } wasmer-wit = { package = "wasmer-interface-types-fl", git = "https://github.com/fluencelabs/interface-types", branch = "impl_refactoring" }
toml = "0.5.6" toml = "0.5.6"
serde = { version = "1.0.111", features = ["derive"] } serde = { version = "1.0.111", features = ["derive"] }