mirror of
https://github.com/fluencelabs/marine.git
synced 2025-03-15 14:00:50 +00:00
initial
This commit is contained in:
parent
2ef43ee778
commit
ee93b8788b
52
Cargo.lock
generated
52
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"
|
||||||
|
@ -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],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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<()>;
|
||||||
}
|
}
|
||||||
|
@ -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>(
|
||||||
|
@ -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![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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<_>>();
|
||||||
|
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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" }
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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((
|
||||||
|
@ -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"] }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user